/* <copyright>
This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
(c) Copyright 2011 Motorola Mobility, Inc.  All Rights Reserved.
</copyright> */

/**
@module js/document/documentManager
@requires montage/core/core
@requires montage/ui/component
@requires js/document/html-document
@requires js/document/text-document
*/

// TODO : Fix deps from Montage V4 Archi

var Montage = require("montage/core/core").Montage,
    Component = require("montage/ui/component").Component,
    Uuid = require("montage/core/uuid").Uuid;

var HTMLDocument = require("js/io/document/html-document").HTMLDocument;
var TextDocument = require("js/io/document/text-document").TextDocument;

var DocumentController = exports.DocumentController = Montage.create(Component, {
    hasTemplate: { value: false },

    _documents: { value: [] },
    _documentsHash: { value: {} },
    _activeDocument: { value: null },
    _iframeCounter: { value: 1, enumerable: false },
    _iframeHolder: { value: null, enumerable: false },
    _textHolder: { value: null, enumerable: false },
    _codeMirrorCounter: {value: 1, enumerable: false},

    _codeEditor: {
        value: {
            "editor": {
                value: null,
                enumerable: false
            },
            "hline": {
                value: null,
                enumerable: false
            }
        }
    },

    activeDocument: {
        get: function() {
            return this._activeDocument;
        },
        set: function(doc) {
            if(this._activeDocument) {
                if(this.activeDocument.documentType === "htm" || this.activeDocument.documentType === "html") {
                    // TODO selection should use the document own selectionModel
                    //this._activeDocument.selectionModel = selectionManagerModule.selectionManager._selectedItems;
                }
                
                this._activeDocument.isActive = false;
            }

            if(this._documents.indexOf(doc) === -1) {
                //this._documentsHash[doc.uuid] = this._documents.push(doc) - 1;
                this._documents.push(doc);
            }

            this._activeDocument = doc;
            this._activeDocument.isActive = true;

            if(this.activeDocument.documentType === "htm" || this.activeDocument.documentType === "html") {
                // TODO selection should use the document own selectionModel
                //selectionManagerModule.selectionManager._selectedItems = this._activeDocument.selectionModel;
            }
        }
    },

    deserializedFromTemplate: {
        value: function() {
            this.eventManager.addEventListener("appLoaded", this, false);
        }
    },

    handleAppLoaded: {
        value: function() {
            this.openDocument({"type": "html"});
        }
    },

    /** Open a Document **/
    openDocument: {
        value: function(doc) {
            var d;

            if(!doc) return false;

            try {
                if (doc.type === 'html' || doc.type === 'htm') {
                    d = Montage.create(HTMLDocument);
                    d.initialize(doc, Uuid.generate(), this._createIframeElement(), this._onOpenDocument);
                } else {
                    d = Montage.create(TextDocument);
                    d.initialize(doc, Uuid.generate(), this._createTextAreaElement(), this._onOpenTextDocument);
                }

            } catch (err) {
                console.log("Could not open Document ",  err);
            }
        }
    },

    closeDocument: {
        value: function(id) {
            var doc = this._findDocumentByUUID(id);
            this._removeDocumentView(doc.container);

            this._documents.splice(this._findIndexByUUID(id), 1);

            if(this.activeDocument.uuid === id && this._documents.length > 0) {
                this.switchDocument(this._documents[0].uuid)
            }
        }
    },

    switchDocument: {
        value: function(id) {
            this._hideCurrentDocument();
            this.activeDocument = this._findDocumentByUUID(id);

            this.application.ninja.stage._scrollFlag = false;    // TODO HACK to prevent type error on Hide/Show Iframe
            this._showCurrentDocument();

            if(this.activeDocument.documentType === "htm" || this.activeDocument.documentType === "html") {
                this.application.ninja.stage._scrollFlag = true; // TODO HACK to prevent type error on Hide/Show Iframe
                // TODO dispatch event here
//                appDelegateModule.MyAppDelegate.onSetActiveDocument();
            }
        }
    },

    switchViews: {
        value: function() {
            this.application.ninja.stage.saveScroll();
            this._hideCurrentDocument();

            if(this.activeDocument.currentView === "design") {
                this._textHolder.style.display = "none";
                this.activeDocument.container.style["display"] = "block";
                this.application.ninja.stage._scrollFlag = true;
                //this._showCurrentDocument();
                this.application.ninja.stage.restoreScroll();

            } else {
                this.application.ninja.stage._scrollFlag = false;    // TODO HACK to prevent type error on Hide/Show Iframe
                var codeview = this._createTextAreaElement();
                this._textHolder.style.display = "block";
                codeview.firstChild.innerHTML = this.activeDocument.iframe.contentWindow.document.body.parentNode.innerHTML;

                this._codeEditor.editor = CodeMirror.fromTextArea(codeview.firstChild, {
                            lineNumbers: true,
                            mode: "htmlmixed",
                            onCursorActivity: function() {
                                DocumentManager._codeEditor.editor.setLineClass(DocumentManager._codeEditor.hline, null);
                                DocumentManager._codeEditor.hline = DocumentManager._codeEditor.editor.setLineClass(DocumentManager._codeEditor.editor.getCursor().line, "activeline");
                            }
                });
                this._codeEditor.hline = DocumentManager._codeEditor.editor.setLineClass(0, "activeline");
            }
        }
    },

    // Document has been loaded into the Iframe. Dispatch the event.
    // Event Detail: Contains the current ActiveDocument
    _onOpenDocument: {
        value: function(doc){
            //var data = DocumentManager.activeDocument;
            //DocumentManager._hideCurrentDocument();

            //stageManagerModule.stageManager.toggleCanvas();

            DocumentController.activeDocument = doc;

            NJevent("onOpenDocument", doc);
//            appDelegateModule.MyAppDelegate.onSetActiveDocument();

        }
    },

    _onOpenTextDocument: {
        value: function(doc) {
            DocumentManager._hideCurrentDocument();
            this.application.ninja.stage._scrollFlag = false;    // TODO HACK to prevent type error on Hide/Show Iframe
            DocumentManager.activeDocument = doc;

            var type;

            switch(doc.documentType) {
                case  "css" :
                    type = "css";
                    break;
                case "js" :
                    type = "javascript";
                    break;
            }

            DocumentManager._codeEditor.editor = CodeMirror.fromTextArea(doc.textArea, {
                        lineNumbers: true,
                        mode: type,
                        onCursorActivity: function() {
                            DocumentManager._codeEditor.editor.setLineClass(DocumentManager._codeEditor.hline, null);
                            DocumentManager._codeEditor.hline = DocumentManager._codeEditor.editor.setLineClass(DocumentManager._codeEditor.editor.getCursor().line, "activeline");
                        }
            });
            DocumentManager._codeEditor.hline = DocumentManager._codeEditor.editor.setLineClass(0, "activeline");

        }
    },

    /**
     * VIEW Related Methods
     */
    // PUBLIC
    ShowActiveDocument: {
        value: function() {
            this.activeDocument.iframe.style.opacity = 1.0;
        }
    },

    // PRIVATE
    _findDocumentByUUID: {
        value: function(uuid) {
            var len =  this._documents.length;
            for(var i = 0; i < len; i++) {
                if(this._documents[i].uuid === uuid) return this._documents[i];
            }

            return false;
        }
    },

    _findIndexByUUID: {
        value: function(uuid) {
            var len =  this._documents.length;
            for(var i = 0; i < len; i++) {
                if(this._documents[i].uuid === uuid) return i;
            }

            return false;
        }
    },

    _hideCurrentDocument: {
        value: function() {
            if(this.activeDocument) {
                this.activeDocument.container.style["display"] = "none";
                if(this.activeDocument.documentType === "htm" || this.activeDocument.documentType === "html") this.application.ninja.stage.toggleCanvas();
            }
        }
    },

    _showCurrentDocument: {
        value: function() {
            if(this.activeDocument) {
                this.activeDocument.container.style["display"] = "block";
                if(this.activeDocument.documentType === "htm" || this.activeDocument.documentType === "html") this.application.ninja.stage.toggleCanvas();
            }
        }
    },

    _removeDocumentView: {
        value: function(node) {
            node.parentNode.removeChild(node);
        }
    },

    reloadDocumentContent: {
        value: function() {
            this.activeDocument._window.location.reload();
        }
    },

    /**
     * Creates a new iFrame element using a new unique ID for it. Returns the iframe ID.
     */
    _createIframeElement: {
        value: function() {
            var e = document.createElement("iframe");
            e.id = this._createIframeID();
            e.style.border = "none";
            e.style.opacity = 0;
            e.height = 1000;
            e.width = 2000;
            e.src = "";

            if(!this._iframeHolder) this._iframeHolder = document.getElementById("iframeContainer");
            
            this._iframeHolder.appendChild(e);

            return e;
        }
    },


    _createIframeID: {
        value: function() {
            return "userDocument_" + (this._iframeCounter++);
        }
    },

    _createTextAreaElement: {
        value: function() {
            var codeMirrorDiv = document.createElement("div");
            codeMirrorDiv.id = "codeMirror_"  + (this._codeMirrorCounter++);

            var textArea = document.createElement("textarea");
            textArea.id = "code";
            textArea.name = "code";

            codeMirrorDiv.appendChild(textArea);

            if(!this._textHolder) this._textHolder = document.getElementById("codeViewContainer");
            this._textHolder.appendChild(codeMirrorDiv);

            return codeMirrorDiv;
        }
    }
});