/* <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> */

////////////////////////////////////////////////////////////////////////
//
var Montage = 		require("montage/core/core").Montage,
    Component = 	require("montage/ui/component").Component,
    HTMLDocument =  require("js/document/document-html").HtmlDocument,
    TextDocument =  require("js/document/document-text").TextDocument;
////////////////////////////////////////////////////////////////////////
//
exports.DocumentController = Montage.create(Component, {
	//
    hasTemplate: {
        value: false
    },

    iframeContainer: {
        value: null
    },

    codeContainer: {
        value: null
    },

    documents: {
        value: []
    },

    _currentDocument: {
            value : null
    },

    currentDocument : {
        get : function() {
            return this._currentDocument;
        },
        set : function(value) {
            if (value === this._currentDocument) {
                return;
            }

            if(this._currentDocument) {
                this._currentDocument.model.currentView.hide();
            }

            this._currentDocument = value;

            if(!value) {
                document.getElementById("iframeContainer").style.display = "block";
                document.getElementById("codeViewContainer").style.display = "block";
            } else if(this._currentDocument.currentView === "design") {
                document.getElementById("codeViewContainer").style.display = "none";
                document.getElementById("iframeContainer").style.display = "block";
                this._currentDocument.model.currentView.show();
                this._currentDocument.model.views.design._liveNodeList = this._currentDocument.model.documentRoot.getElementsByTagName('*');
            } else {
                document.getElementById("iframeContainer").style.display = "none";
                this._currentDocument.model.parentContainer.style["display"] = "block";
                this._currentDocument.model.currentView.show();
            }

        }
    },

    deserializedFromTemplate: {
        value: function() { //TODO: Add event naming consistency (save, fileOpen and newFile should be consistent, all file events should be executeFile[operation name])
            this.eventManager.addEventListener("appLoaded", this, false);
            this.eventManager.addEventListener("executeFileOpen", this, false);
            this.eventManager.addEventListener("executeNewFile", this, false);
            this.eventManager.addEventListener("executeSave", this, false);
            this.eventManager.addEventListener("executeSaveAs", this, false);
            this.eventManager.addEventListener("executeSaveAll", this, false);
            this.eventManager.addEventListener("executeFileClose", this, false);
            this.eventManager.addEventListener("executeFileCloseAll", this, false);
        }
    },

    didCreate: {
        value: function() {
            this.iframeContainer = document.getElementById("iframeContainer");
            this.codeContainer = document.getElementById("codeViewContainer");
        }
    },

	//TODO: Ensure these APIs are not needed
	redirectRequests: {
    	value: false
    },
	////////////////////////////////////////////////////////////////////
	//
    handleWebRequest: {
    	value: function (request) {
    		//TODO: Check if frameId is proper
    		if (this.redirectRequests && request.parentFrameId !== -1) {
    			//Checking for proper URL redirect (from different directories)
    			if (request.url.indexOf('js/document/templates/banner') !== -1) {
					return {redirectUrl: this.application.ninja.coreIoApi.rootUrl+this.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]+request.url.split(chrome.extension.getURL('js/document/templates/banner/'))[1]};
				} else if (request.url.indexOf('js/document/templates/html')  !== -1) {
					return {redirectUrl: this.application.ninja.coreIoApi.rootUrl+this.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]+request.url.split(chrome.extension.getURL('js/document/templates/html/'))[1]};
				} else if (request.url.indexOf('js/document/templates/app')  !== -1) {
					return {redirectUrl: this.application.ninja.coreIoApi.rootUrl+this.documentHackReference.root.split(this.application.ninja.coreIoApi.cloudData.root)[1]+request.url.split(chrome.extension.getURL('js/document/templates/app/'))[1]};
				} else {
					//Error, not a valid folder
				}
			}
		}
    },
    ////////////////////////////////////////////////////////////////////
	//
    handleAppLoaded: {
        value: function() {
            //Checking for app to be loaded through extension
            var check;
            if (chrome && chrome.app) {
            	check = chrome.app.getDetails();
            }
            if (check !== null) {
            	//Adding an intercept to resources loaded to ensure user assets load from cloud simulator
            	chrome.webRequest.onBeforeRequest.addListener(this.handleWebRequest.bind(this), {urls: ["<all_urls>"]}, ["blocking"]);
            }
        }
    },
	////////////////////////////////////////////////////////////////////


    handleExecuteFileOpen: {
        value: function(event) {
            var pickerSettings = event._event.settings || {};
            if (this.application.ninja.coreIoApi.cloudAvailable()) {
                pickerSettings.callback = this.openFileWithURI.bind(this);
                pickerSettings.pickerMode = "read";
                pickerSettings.inFileMode = true;
                this.application.ninja.filePickerController.showFilePicker(pickerSettings);
            }
        }
    },

    handleExecuteNewFile: {
        value: function(event) {
            var newFileSettings = event._event.settings || {};
            if (this.application.ninja.coreIoApi.cloudAvailable()) {
                newFileSettings.callback = this.createNewFile.bind(this);
                this.application.ninja.newFileController.showNewFileDialog(newFileSettings);
            }
        }
    },
	////////////////////////////////////////////////////////////////////
	//
    handleExecuteSave: {
    	value: function(event) {
    		//
    		if((typeof this.currentDocument !== "undefined") && this.application.ninja.coreIoApi.cloudAvailable()){
    			//Currently we don't need a callback handler
    			//this.activeDocument.model.save(this.saveExecuted.bind(this));
    			this.currentDocument.model.save();
    		} else {
    			//Error: cloud not available and/or no active document
    		}
		}
    },
    ////////////////////////////////////////////////////////////////////
	//
    saveExecuted: {
    	value: function (value) {
    		//File saved, any callbacks or events should go here (must be added in handleExecuteSave passed as callback)
    	}
    },
    ////////////////////////////////////////////////////////////////////
	//TODO: Check for appropiate structures
    handleExecuteSaveAll: {
    	value: function(event) {
           //
    		if((typeof this.currentDocument !== "undefined") && this.application.ninja.coreIoApi.cloudAvailable()){
    			//
    			this.currentDocument.model.saveAll();
    		} else {
    			//TODO: Add error handling
    		}
		}
    },
    ////////////////////////////////////////////////////////////////////
    handleExecuteSaveAs: {
        value: function(event) {
            var saveAsSettings = event._event.settings || {};
            if((typeof this.currentDocument !== "undefined") && this.application.ninja.coreIoApi.cloudAvailable()){
                saveAsSettings.fileName = this.currentDocument.model.file.name;
                saveAsSettings.folderUri = this.currentDocument.model.file.uri.substring(0, this.currentDocument.model.file.uri.lastIndexOf("/"));
                saveAsSettings.callback = this.saveAsCallback.bind(this);
                this.application.ninja.newFileController.showSaveAsDialog(saveAsSettings);
            }
        }
    },
    ////////////////////////////////////////////////////////////////////
    handleExecuteFileClose:{
        value: function(event) {
            this.closeFile(this.currentDocument);
        }
    },
    ////////////////////////////////////////////////////////////////////
    //TODO: Is this used, should be cleaned up
    handleExecuteFileCloseAll:{
		value: function(event) {
			if(this.currentDocument && this.application.ninja.coreIoApi.cloudAvailable()){
				while(this.currentDocument.length > 0){
					this.closeDocument(this.currentDocument[this.currentDocument.length -1].uuid);
				}
			}
		}
	},
	////////////////////////////////////////////////////////////////////
	//
    createNewFile:{
        value:function(newFileObj){
            //
            if(!newFileObj) return;
            //
            this.application.ninja.ioMediator.fileNew(newFileObj.newFilePath, newFileObj.fileTemplateUri, this.openNewFileCallback.bind(this), newFileObj.template);
        }
    },
	////////////////////////////////////////////////////////////////////
	
    /**
     * Public method
     * doc contains:
     *      type : file type, like js, css, etc
     *      name : file name
     *      source : file content
     *      uri : file uri
     */
    openNewFileCallback:{
        value:function(doc){
            var response = doc || null;//default just for testing
            if(!!response && response.success && (response.status!== 500) && !!response.uri){

                this.isNewFilePath = true;//path identifier flag
                this.creatingNewFile = true;//flag for timeline to identify new file flow

                this.application.ninja.ioMediator.fileOpen(response.uri, this.openFileCallback.bind(this));
            } else if(!!response && !response.success){
                //Todo: restrict directory path to the sandbox, in the dialog itself
                alert("Unable to create file.\n [Error: Forbidden directory]");
            }
        }
    },

    openFileWithURI: {
        value: function(uriArrayObj) {
            var uri = "", fileContent = "", response=null, filename="", fileType="js";
            if(!!uriArrayObj && !!uriArrayObj.uri && (uriArrayObj.uri.length > 0)){
                uri = uriArrayObj.uri[0];
            }
            //console.log("URI is: ", uri);
            if(!!uri){
                this.application.ninja.ioMediator.fileOpen(uri, this.openFileCallback.bind(this));
            }
        }
    },

    ////////////////////////////////////////////////////////////////////
    //
    openFileCallback:{
        value:function(response){
            //TODO: Add UI to handle error codes, shouldn't be alert windows
            if(!!response && (response.status === 204)) {

                if((typeof this.isNewFilePath === 'undefined') || (this.isNewFilePath !== true)){//not from new file flow
                    this.creatingNewFile = false;
                }
                this.isNewFilePath = false;//reset path identifier flag

            	//Sending full response object
                this.openDocument(response);

            } else if (!!response && (response.status === 404)){
                alert("Unable to open file.\n [Error: File does not exist]");
            } else if (!!response && (response.status === 500)){
                alert("Unable to open file.\n Check if Ninja Local Cloud is running.");
            } else{
                alert("Unable to open file.");
            }

        }
    },
	////////////////////////////////////////////////////////////////////
	//
    saveAsCallback:{
        value:function(saveAsDetails){
            var fileUri = null, filename = saveAsDetails.filename, destination = saveAsDetails.destination;
            //update document metadata
            this.currentDocument.model.file.name = ""+filename;
            //prepare new file uri
            if(destination && (destination.charAt(destination.length -1) !== "/")){
                destination = destination + "/";
            }
            fileUri = destination+filename;

            this.currentDocument.model.file.uri = fileUri;
            //save a new file
            //use the ioMediator.fileSaveAll when implemented
            this.currentDocument.model.file.name = filename;
            this.currentDocument.model.file.uri = fileUri;
            this.currentDocument.model.save();
        }
    },

    ////////////////////////////////////////////////////////////////////
    openDocument: {
        value: function(file) {
        	var template, dimensions;

            // TODO: HACKS to remove
			this.documentHackReference = file;
            document.getElementById("iframeContainer").style.overflow = "hidden";
			//
			switch (file.extension) {
				case 'html':

                    if (file.content.body.indexOf('Ninja-Banner Dimensions@@@') !== -1) {
                        dimensions = (file.content.body.split('Ninja-Banner Dimensions@@@'))[1].split('-->')[0].split('x');
                        dimensions = {width: parseInt(dimensions[0]), height: parseInt(dimensions[1])};
                        template = {type: 'banner', size: dimensions};
                    }

					//Open in designer view
                    this.redirectRequests = false;
                    Montage.create(HTMLDocument).init(file, this.application.ninja, this.application.ninja.openDocument, 'design', template);
					break;
				default:
                    //Open in code view
                    Montage.create(TextDocument).init(file, this.application.ninja, this.application.ninja.openDocument, 'code');
                    break;
			}
        }
    },
	////////////////////////////////////////////////////////////////////
	
	openProjectWithURI: {
        value: function(uri) {
            console.log("URI is: ", uri);
        }
    },

    closeFile: {
        value: function(document) {
            document.closeDocument(this.application.ninja, this.application.ninja.closeFile);
        }
    }
});