define(function(require) {

    var CodeView = require("ui/code/CodeView"),
        UIUtil = require("utils/UIUtil"),
        SnippetMap = require("utils/SnippetMap"),
        fileInput = null,
        filename = "",
        filePath = localStorage.getItem("glcFilePath"),
        GLCInterface = null,
        MainController = null,
        isDirty = localStorage.getItem("glcIsDirty", "false") === "true";


    function init(pGLCInterface, pMainController) {
        GLCInterface = pGLCInterface;
        MainController = pMainController;
        CodeView.init(this);
        setUpFileInput();
        setTitleWithPath();
    }

    function setUpFileInput() {
        fileInput = UIUtil.createInput("file", null, null, null, "change", chooseFile);
    }

    function chooseFile(event) {
        // when cancelling, sometimes you get no event
        // sometimes you get an event with 0 files.
        if(event.target.files.length < 1) return;

        var file = event.target.files[0],
            reader = new FileReader();
        reader.onload = function() {
            CodeView.setCode(reader.result, true);
            compile();
        }
        reader.readAsText(file);
    }

    function newFile(ignoreChanges) {
        if(ignoreChanges === true || !isDirty || window.confirm("Any unsaved changes will be lost. Create new file?")) {
            CodeView.newFile();
            MainController.reset();
            setFilePath(null),
            setDirty(true);
        }
    }

    function open() {
        if(!isDirty || window.confirm("Any unsaved changes will be lost. Open new file?")) {
            if(glcConfig.isStandalone) {
                openNative();
            }
            else {
                fileInput.click();
            }
        }
    }

    function openNative() {
        var remote = nodeRequire("remote"),
            dialog = remote.require("dialog"),
            options = {
                filters: [
                    {
                        name: "GLC Source Files", 
                        extensions: ["js", "glc"]
                    }
                ]
            }; 
            
        dialog.showOpenDialog(options, onOpenFileChosen);
    }

    function onOpenFileChosen(files) {
        var fs = nodeRequire("fs");
        setFilePath(files[0]);
        fs.readFile(filePath, function(err, data) {
            CodeView.setCode(data.toString());
            setDirty(false);
        });
    }

    function save() {
        if(glcConfig.isStandalone) {
            saveNative();
        }
        else {
            saveWeb();
        }
    }

    function saveNative() {
        console.log("filename is " + filePath);
        if(filePath == null || filePath === "" || filePath === "null") {
            console.log("saving as");
            saveAs();
        }
        else {
            console.log("saving");
            var fs = nodeRequire("fs");
            fs.writeFile(filePath, CodeView.getCode(), function(err) {
                if(err) {
                    alert(err);
                }
                else {
                    setDirty(false);
                }
            });
        }
    }

    function saveWeb() {
        var result = window.prompt("Please enter a file name. File will be saved in current browser download location.", filename);
        if(result) {
            filename = result;
            if(filename.split(".").length < 2) {
                filename += ".glc";
            }
            var link = document.createElement("a");
            link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(CodeView.getCode()));
            link.setAttribute('download', filename);
            link.click();
        }
        else if(result === "") {
            window.alert("No file name entered. File not saved.");
        }
    }

    function saveAs() {
        var remote = nodeRequire("remote"),
            dialog = remote.require("dialog"),
            options = {
                filters: [
                    {
                        name: "GLC Source Files", 
                        extensions: ["js", "glc"]
                    }
                ]
            }; 
            
        dialog.showSaveDialog(options, onSaveFileChosen);
    }

    function onSaveFileChosen(file) {
        if(file) {
            setFilePath(file);
            saveNative();
        }
    }

    function compile() {
        // TODO: reset and clear renderlist
        var script = document.getElementById("loaded_script");
        if(script) {
            document.head.removeChild(script);
        }

        script = UIUtil.createScript("loaded_script", CodeView.getCode(), document.head);


        reload();
    }

    function reload() {
        MainController.reset();
        if(window.onGLC) {
            window.onGLC(GLCInterface);
        }

    }

    function getView() {
        return CodeView;
    }

    function setCodeFromCache(code) {
        CodeView.setCode(code, true);
    }

    function onSnippet(snippetName) {
        CodeView.insertCode(SnippetMap.getSnippet(snippetName));
    }

    function setDirty(dirty) {
        isDirty = dirty;
        MainController.setDirty(isDirty);
        localStorage.setItem("glcIsDirty", isDirty ? "true" : "false");
    }

    function getDirty() {
        return isDirty;
    }

    function setFilePath(path) {
        filePath = path;
        localStorage.setItem("glcFilePath", filePath);
        setTitleWithPath();
    }

    function setTitleWithPath() {
        if(glcConfig.isStandalone) {
            var electron = nodeRequire("electron");
            if(filePath == null || filePath === "" || filePath === "null") {
                electron.remote.getCurrentWindow().setTitle("GIF Loop Coder");
            }
            else {
                electron.remote.getCurrentWindow().setTitle("GIF Loop Coder - " + filePath);
            }
        }
    }


    return {
        init: init,
        newFile: newFile,
        open: open,
        save: save,
        saveAs: saveAs,
        compile: compile,
        getView: getView,
        setCodeFromCache: setCodeFromCache,
        onSnippet: onSnippet,
        setDirty: setDirty,
        getDirty: getDirty
    };

});
@@ -2234,24 +2234,68 @@
 en(files) %7B%0A
+        if(files && files.length %3E 0) %7B%0A    
         var 
@@ -2318,32 +2318,36 @@
 (%22fs%22);%0A        
+   
+ 
 setFilePath(file
@@ -2353,16 +2353,20 @@
 es%5B0%5D);%0A
+    
         
@@ -2405,24 +2405,28 @@
 rr, data) %7B%0A
+    
             
@@ -2464,32 +2464,36 @@
 ));%0A            
+    
 setDirty(false);
@@ -2497,27 +2497,41 @@
 e);%0A        
-%7D);
+    %7D);%0A        %7D
 %0A    %7D%0A%0A    

fix when cancelling open file dialog