(function() {

    // Design
    // The node webkit interface for accessesing system file dialog's is not intuitive.
    // It is based around having clickable html <input tags> see here : https://github.com/nwjs/nw.js/wiki/File-dialogs 
    // Thus, to encapsulate and abstract the dialogs on node webkit the implementation is a bit tricky
    // 1) We have to have some html elements embedded on the page. We do this by exposing a 'ticFileDialogs' directive. It's
    // 	  only job is to insert our input html tags into the page. We could do this dynamically by inserting programmatically into the body
    //	  but this gives the API user a bit more flexability.
    // 2) When an API is invoked we programatically 'click' on element, and attach a listener as per node webkit instructions
    //

    'use strict';
    let openFilePathInput;
    let saveFilePathInput;
    /*global File*/

    (function() {

        angular.module('ti_common').service('ticFileDialogs', fileDialogs);

        fileDialogs.$inject = ['$q', '$timeout', 'ticFileFactory', '$log'];

        function fileDialogs($q, $timeout, ticFileFactory, $log) {
            let currentHandler;

            function commonFilePath(element, action) {

                if( currentHandler ){
                    // There is no way to hook into cancel in nw file dialogs,
                    // so to avoid get multiple call backs we have to make sure there is only 1
                    // active handler at a time.. 
                    element.removeEventListener('change', currentHandler);
                }

                return $q(function(resolve) {
                    currentHandler = function fileLoadHandler() {
                        element.removeEventListener('change', fileLoadHandler, false);
                        let fullpath = this.value;
                        let file = action(fullpath);
                        let files = [];
						files.push(file);
						$log.debug('2 saveFile()' + fullpath);
                        resolve(files);
                    };
                    // this allows us to handle cancel appropriately
                    element.files.clear();
                    element.addEventListener('change', currentHandler, false);
                    // we want have the click happen in the next event loop
                    // to avoid causing an angular already in $digest phase issue
                    $timeout(element.click.bind(element));
                });
            }

            let dialogSettings = {
                acceptTypes: '',
                defaultName: ''
            };
            // open an existing file
            function openFile(title: string, exts: RegExp);
            function openFile(title: string, exts: string);
            function openFile(title: string, exts: any) {
                //title not used atm due to nw limitation
                if (typeof exts === 'string') {
                    dialogSettings.acceptTypes = (exts) ? exts : '';
                } else {
                    dialogSettings.acceptTypes = '';
                }
                return commonFilePath(openFilePathInput, ticFileFactory.create);
            }

            function saveFile(title: string, name: string, ext: string) {
                //title not used atm due to nw limitation
                dialogSettings.acceptTypes = ext;
				dialogSettings.defaultName = name + dialogSettings.acceptTypes;
				$log.debug('1 saveFile() ' + dialogSettings.defaultName );
                return commonFilePath(saveFilePathInput, ticFileFactory.create)
                    .then((files) => {
                        return files[0];
                    });
            }

            return {
                openFile: openFile,
                saveFile: saveFile,
                dialogSettings: dialogSettings
            };
        }

    })();


    (function() {

        angular.module('ti_common').directive('ticFileDialogs', ticFileLoadDialog);

        function ticFileLoadDialog() {

            let directive = {
                restrict: 'E',
                templateUrl: 'ti_common/nw/file_dialogs.html',
                link: link,
                scope: {},
                controller: ticFileDialogsCtrl,
                controllerAs: 'vm',
                bindToController: true

            };

            function link(scope, element) {
                openFilePathInput = element.children()[0]; // select only existing file paths ( to load files)
                saveFilePathInput = element.children()[1]; // select existing or new file paths
            }

            return directive;
        }

        ticFileDialogsCtrl.$inject = ['ticFileDialogs'];
        function ticFileDialogsCtrl(ticFileDialogs) {
            let vm = this;
            vm.dialogSettings = ticFileDialogs.dialogSettings;
        }

    })();



} ());