var DESKTOP = null;
var GRAPHIC_UNIT = null;
var ROOT_VIEW = "kubbeview/";

var defaults = {

    initFile: "initKubbe_2.js",
    i18nPreload: ["Components"],
    defaultLanguage: DESKTOP_LANG,
    defaultProperties: "es_ES",
    ldap: false,
    noI18N: false,
    isLogged: true,
    exitAction: "none",
    noPeople: false,
    noLogin: false
};


if (! EXTERNAL_CONFIG_DEFAULT) {
    var EXTERNAL_CONFIG_DEFAULT = {};
}

var DESKTOP_CONFIG_DEFAULT = $.extend({}, defaults, EXTERNAL_CONFIG_DEFAULT);

function Desktop() {      
    var view = null;
    var model = null;
    var controller = null;    
    
    function View() {
         
        this.openBox = function(data) {
            //var heigth = ___getPageSize()[1];
            //data.height=heigth;  //$(document.body).height();  
            
            data.height=$(document).height();  //$(document.body).height(); 
            
            if (!data.top) data.top=document.documentElement.scrollTop+100;                
            $(document.body).append(TemplateKubbe.process("kubbeview/escritorio/template/dialogWindow.html",data));                    
                          
            $("div[@id=escritorioDialog]").fadeTo("fast",0.7); 
            
            return $("div[@id=windowDialog]", document.body).get(0);            
        }
        
        this.closeBox = function() {
            $("div[@id=escritorioWindow]").remove();
            $("div[@id=escritorioDialog]").remove();                 
        }
        
        this.reset = function() {
            $(document.body).empty();       
        }
        this.loadInlineHelp = function(options){
            this.inlineHelp = new InlineHelpComponent(options);
        }
        this.changeInlineHelp = function(data){
            this.inlineHelp.changeInlineHelp(data);
        }
        this.reloadComponentI18N = function() {
            var langExt = '_'+model.getLanguageCode();
            if(langExt == "_es_ES") {
                langExt = "";
            }
            $.ajax({
                url: URL_APL+"kubbeview/i18n/Components"+langExt+".properties",
                dataType: "script",
                success: function (data, textStatus) {
                    eval(data);
                    var keys = KUBBEI18N_MODULE_LANGUAGE;
                    if (keys) KUBBEI18N.addKeys(keys);

                }
            })
            return;
        }
    }
    
    function Model() {
        this.user = null;

        var config = DESKTOP_CONFIG_DEFAULT;  
        var registerUG = {};  //register of load graphic units;
        var registerLoad = {};
        var apiDesktop = null;
        var listeners = [];
        var language = null;
        var loadIndex = 0;
        var companyConfigParam = null;//to cache the company configuration parameter on client side
        
        this.configureDesktop = function() {
      /*    try {
               
                if (DESKTOP_CONFIG) {
                    for (var x in DESKTOP_CONFIG) {
                        config[x] = DESKTOP_CONFIG[x];
                    }
                }
            } catch (exception) {
              
            }
         */ 
        }

        this.hadLogged = function() {
            return this.user!=null;
        }
        this.getKubbeLanguageCode = function(lang){
            if (lang != null) {
                if(lang == "es") {
                    language = "es_ES";
                } else if (lang == "pt") {
                    language = "pt_PT";
                } else if (lang == "gl") {
                    language = "gl_ES";
                } else if (lang == "ca") {
                    language = "ca_ES";
                } else if (lang == "fr") {
                    language = "fr_FR";
                } else if (lang == "en") {
                    language = "en_GB";
                } else {
                    language = "en_GB";
                }
            }
            return language;
        }
        this.getLanguageCode = function() {     
            if (!language) {                
                language = this.getKubbeLanguageCode(language);
                }
            return language;
        }
        
        this.getLanguageExt = function() {
            var code = this.getLanguageCode();
            if (code==this.getConfig().defaultProperties) return "";
            else return "_"+code;
        }
        
        this.getConfig = function() {
            return config;
        }
        
        this.configureAjax = function () {
            $.ajaxSetup({    
                scriptCharset: "utf-8",
                contentType: "application/x-www-form-urlencoded; charset=utf-8", 
                error: function(XMLHttpRequest, textStatus) {                    
                     var status = XMLHttpRequest.statusText;      
                     var is = controller.processEvent(controller.IS_ERROR_I18N, status);
                     if (!is)
                         alert(KUBBEI18N.keyOnly("kubbe.serverError"));
                       // alert("Se ha producido un error en la comunicaci&ocaute con el servidor.");
                }
            });
        }
        
        this.configureUI = function() {
            $.datepicker.setDefaults($.datepicker.regional['']);
            $.datepicker.setDefaults({
                showOn: "both",    
                changeFirstDay: false,
                buttonImageOnly: true,
                dateFormat: 'dd/mm/yy',
                buttonImage: URL_APL+"kubbeview/STYLEdefault/img/ico_selecDia.png"
            });
        }
        
        //Paramters: api object, arrays keys to register the api object
        this.registerAPI = function(api, registerData) {
            if (registerData) {                
                for (var i=0; i<registerData.length; i++) {
                    registerUG[registerData[i]]=api;
                }
            }
        }
        
        this.sendMessage = function(key, message) {
            for (var x in registerUG) {
                if (x==key) registerUG[key].inbox(message);
            }                
        }
         
        this.loadJS = function(url, fn) {
            $.getScript(url, fn);
        }
        
        this.loadCSS = function(url) {
            
            /* Try on demand load */
            var $head = $("head");
            var $style = $("link[href=" + url + "]", $head);
            
            var $hook = $("link[mandatory=true]:first", $head);
            
            if ($style.length) return null;
            if ($hook.length) {
                    $hook.before("<link rel='stylesheet' type='text/css' " +
                    "href='" + url + "'/>");
            } else {
                    $("head").append("<link rel='stylesheet' type='text/css' href='"+url+"'/>");
            }
        }
        
        this.isErrorI18N = function(url) {
            var re = new RegExp("[\\w\\W].properties")
            if (url.match(re)) {
                loadIndex=0;                
                re = new RegExp("[\\w\\W]_[a-zA-Z]{2,2}.properties")
                if (url.match(re)) {
                    var newURL = url.substring(0,url.indexOf("_"))+".properties";
                    this.loadI18N([newURL],this.getRegisterLoad(url), true);
                } else {
                    this.loadModule(this.getRegisterLoad(url));
                }
                return true;
            };
            return false;
        }
        
        this.getUrlI18N = function(name) {
            return URL_APL+ROOT_VIEW+"i18n/"+name+this.getLanguageExt()+".properties";
        }
        
        this.loadI18N = function(files, endAction, url) {     
            var urlLoad = url?files[loadIndex]:this.getUrlI18N(files[loadIndex]);
            this.registerLoad(urlLoad,endAction);

            $.ajax({
                url: urlLoad,
                dataType: "script",
                success: function (data, textStatus) {
                    // data could be xmlDoc, jsonObj, html, text, etc...
                    eval(data);
                    var keys = KUBBEI18N_MODULE_LANGUAGE;
                    if (keys) KUBBEI18N.addKeys(keys);
                    loadIndex++;

                    if (files.length==loadIndex) {
                        loadIndex=0;
                        if(!endAction) controller.processEvent(controller.EXECUTE_SCRIPT);
                        else {
                            model.loadModule(endAction);                        
                        }
                    } else model.loadI18N(files);
                    
                }

            })
        }
        
        this.registerLoad = function(key, value) {
            registerLoad[key] = value;
        }
        
        this.getRegisterLoad = function(key) {

            return registerLoad[key];
        }
        
        this.loadModule = function(data) {            
            var api = new DesktopAPI(data.config);
            this.registerEventKboxWindows(api, data.config.wc);
            model.registerAPI(api, data.config.register);
            if (data) model.loadJS(data.urlJS, function() { new DESKTOP.graphicUnit(api) })            
        }
        
        this.registerEventKboxWindows = function(API, windowComponent) {            
            if (windowComponent) {
                windowComponent.onedit = function() {
                    API.onedit();
                }                
                windowComponent.setAPI(API);
            }
        }
        
        
        this.setModules = function(modules) {
            this.modules = {};
            for (var i=0; i<modules.length; i++) {
                this.modules[modules[i].dataContent]= {name: modules[i].dataContent,
                                                       urlJs: modules[i].urlJs,
                                                       urlCss: modules[i].urlCss,
                                                       config: modules[i].configContent,
                                                       title: modules[i].title,
                                                       options: modules[i].optionsTitle,
                                                       userPermission: modules[i].userPermission,
                                                       typeKbox: modules[i].typeKbox
                                                   };
            }
        }
        
        this.getModule = function(key) {
            return this.modules[key];
        }
        
        this.setUser  = function(user) {
            this.user = user;
        }
        
        this.getUser = function() {
            return this.user;
        }
        
        this.setLanguage = function(languageKey) {
            language = languageKey;
        }
        
        this.saveCookie = function(data) {
            $.cookie(data.key, data.value, {expires: data.expires});
        }
        
        this.removeCookie = function(key) {
            $.cookie(key,"", {expires:-1});
        }
        
        this.recoveryCookie = function(key) {
            return $.cookie(key);
        }
        
        this.setListenerDesktop = function(api) {
            apiDesktop = api;
        }
        
        this.getListenerDesktop = function() {
            return apiDesktop;
        }
        //to cache the company configuration parameter on client side
        this.setCompanyConfigParam = function(data){
            companyConfigParam = data;
        }
        this.getCompanyConfigParam = function(){
            return companyConfigParam;
        }

        this.hasPermission = function(permission) {
            var has = false;
            var userPermissions = this.getUser().permissionsMap;
            for (x in userPermissions) {
                if (permission==x) {
                    has=true;
                    break;
                }
            }
            return has;
        }

        this.setHasBulletin= function(flag){            
            this.hasBulletin = flag;
        }
        this.getHasBulletin=function(){
            return this.hasBulletin;
        }
         
    }
    
    function Controller() {        
        this.INIT = "init";
        this.EXECUTE_SCRIPT = "executeScript";        
        this.GET_HAS_BULLETIN = "getHasBulletin";
        this.LOAD_GRAPHIC_UNIT = "loadGraphicUnit";
        this.LOADING_GRAPHIC_UNIT = "loadingGraphicUnit";
        this.REQUEST_MODULES = "requestModules";
        this.LOAD_I18N = "loadI18N";
        this.ACTIVE_DIALOG = "activeDialog";
        this.DESACTIVE_DIALOG = "desactiveDialog";
        this.REQUEST_INFO_USER = "requestInfoUser";
        this.REQUEST_USER_INFO = "requestUserInfo";
        this.GET_INFO_USER = "getInfoUser";
        this.GET_USER_INFO = "getUserInfo";
        this.SEND_MESSAGE = "sendMessage";
        this.SEND_LOGIN = "sendLogin";
        this.GET_CONFIG = "getConfig";   
        this.SET_LANGUAGE = "setLanguage";
        this.RESET_INTERFACE = "resetInterface";
        this.SAVE_COOKIE = "saveCookie";
        this.REMOVE_COOKIE = "removeCookie";
        this.RECOVERY_COOKIE = "recoveryCookie";
        this.IS_ERROR_I18N = "isErrorI18N";
        this.RECOVERY_CONFIG = "recoveryConfig";
        this.SAVE_CONFIG = "saveConfig";
        this.LOAD_SCRIPT = "loadScript";
        this.GET_INFO_MODULE = "getInfoModule";
        this.GET_LANGUAGE = "getLanguage";
        this.ADD_PAGE = "addPage";
        this.CLOSE_PAGE = "closePage";
        this.SET_LISTENER_DESKTOP = "setListenerDesktop";
        this.ADD_KBOX = "addKbox";
        this.HAS_PERMISSION = "hasPermission";
        this.RESET_INFO = "resetInfo";
        this.IS_I18N = "isI18N";
        this.USER_STATUS_CHANGE = "userStatusChange";
        this.HAD_LOGGED = "hadLogged";        
        this.REFRESH_PAGE = "refreshPage";
        this.CACHE_CONFIG_PARAM = "cacheConfigParam";//this code is added to cache the company configuration parameter on client side
        this.GET_COMPANY_CONFIG_PARAM = "getConfigParam";
        this.EXIT = "exit";
        this.LOAD_IN_LINE_HELP = "loadInlineHelp";
        this.CHANGE_IN_LINE_HELP = "changeInlineHelp";
        this.GET_LANGUAGE_EXT = "getLanguageExt";
        this.REMOVE_CONFIG = "removeConfig";
        this.FIND_BULLETIN_CONTENT = "FindBulletinContent";
        
        this.ajaxCom = Util.ajaxComunication;
        this.ajaxComSyncr = function(url, datos) {
            var controller = this;
            var dataReturn = null;
            $.ajax({
                url: URL_APL+url,
                type: "POST",
                dataType: "json",
                contentType: "application/x-www-form-urlencoded; charset=utf-8", 
                data: datos,
                processData: true,
                async: false,
                success: function (dataRecv) {
                    dataReturn = dataRecv.response;                
                }
            });
     
                return dataReturn;
        
            }        
        this.processEvent = Util.processEvent;
        
        this.executeScript =  function(data) {
            model.loadJS(URL_APL+"kubbeview/light/config/"+model.getConfig().initFile);
        }
        
        this.userStatusChange = function(){
            controller.ajaxCom(URL_APL+"basic/userConnectionStatusAction.do", true, {});
        }
        
        this.isErrorI18N = function(url) {
             var is = model.isErrorI18N(url);
             return is;
        }
        
        this.isI18N = function() {
            return !model.getConfig().noI18N;
        }
        
        this.init = function() {     
            model = new Model();
            view = new View();
            model.configureDesktop();
            model.configureAjax();
            model.configureUI();
            var language = model.getKubbeLanguageCode(DESKTOP_LANG);
            model.setLanguage(language);
            controller.processEvent(controller.REQUEST_MODULES);            
        }
        
        this.loadingGraphicUnit = function(data) {
            model.loadCSS(data.urlCSS);
            model.loadI18N([data.config.name], {urlJS: data.urlJS, config: data.config});                        
        }
        
        this.loadGraphicUnit = function(data) {
        
            var module = data;
            if (!data.urlJs) {
                module = model.getModule(data.name);   
            }

            var style_replace = data.style_replace || DESKTOP_STYLE;
            controller.processEvent(controller.LOADING_GRAPHIC_UNIT, {urlJS: URL_APL+ROOT_VIEW+module.urlJs,
                                                                          urlCSS: URL_APL+ROOT_VIEW+module.urlCss.replace("$style$",style_replace),
                                                                          userPermission: module.userPermission,
                                                                          config:data});                        
        }        
        
        this.requestModules = function() {
            controller.ajaxCom(URL_APL+"escritorio/FindAllComponents.do", true, {});
        }
    
        this.JsonFindAllComponents = function(modules) {
            model.setModules(modules);           
            controller.processEvent(controller.LOAD_I18N);
        }
        
        this.loadI18N = function() {
            var files = DESKTOP_CONFIG_DEFAULT.i18nPreload;
            model.loadI18N(files);
        }
        
        this.activeDialog = function(data) {
            return view.openBox(data);
        }        
        
        this.desactiveDialog = function() {
            view.closeBox();
        }   
        
        this.requestInfoUser = function() {            
            var user = controller.ajaxComSyncr("basic/logonInfo.do", {});
            model.setUser(user);
            return user;
        }
        this.requestUserInfo = function(userId) {
            var user = controller.ajaxComSyncr("basic/FindUser.do", {userId:userId});            
            return user;
        }
        
        this.getInfoModule = function(key) {
            return model.getModule(key)
        }
    
        /*
        this.jsonLoginInfoAction = function(user) {
            model.setUser(user);
            controller.processEvent(controller.EXECUTE_SCRIPT);
        } */   
        
        this.resetInfo = function() {
            model.setUser(controller.processEvent(controller.REQUEST_INFO_USER));
        }

        this.getHasBulletin = function(){
            return model.getHasBulletin();
        }

        this.getInfoUser = function() {            
            var user = model.getUser();            
            if (!user) return controller.processEvent(controller.REQUEST_INFO_USER);
            return user;
        }           
        this.getUserInfo = function(userId) {
            return controller.processEvent(controller.REQUEST_USER_INFO,userId);
        }
        this.sendMessage = function(data) {
            model.sendMessage(data.key, data.message);
        }
        
        this.sendLogin = function(data, API) {
            var action = model.getConfig().ldap?"logonLdapSupported":"logon";
            controller.ajaxCom(URL_APL+"basic/"+action+".do", true, data.login, data.API);
        };
        //cache the company configuration parameter on client side
        this.getConfigParam = function(){
            var configParamMap = model.getCompanyConfigParam();
            
            if(!configParamMap){
              return controller.processEvent(controller.CACHE_CONFIG_PARAM);
            }
            return configParamMap;
        }
        
        this.cacheConfigParam = function(data){
            var configData = controller.ajaxComSyncr("basic/GetConfigurationJsonAction.do", {});
            model.setCompanyConfigParam(configData);
            return configData;
        }
        
        this.jsonLoginAction = function(data, page, API) {
            if (data) {                
                var language = model.getKubbeLanguageCode(data.userLanguage);                 
                model.setLanguage(language);                
                model.loadJS(URL_APL + "kubbeview/light/lib/ui.datepicker-"+model.getLanguageCode(language)+".js");
                model.setUser(data);
                var component = API.getComponent();
                if (component.onlogon) {
                    component.onlogon(data.nombre?true:false);
                }
                controller.FindBulletinContent(API);
            } else {
                var component = API.getComponent();
                if (component.onlogon) component.onlogon(false);
            }            
            view.reloadComponentI18N();
            controller.processEvent(controller.CACHE_CONFIG_PARAM);
        }
        
        this.FindBulletinContent = function(API) {
            var communities = API.getCommunitiesId();
            controller.ajaxCom(URL_APL+"bulletin/FindBulletinAction.do", false,{idCommunity:communities});
        }
        this.JsonFindBulletinAction = function(data){            
            if (data.length > 0){
                model.setHasBulletin(true);
            }
            else {
                model.setHasBulletin(false);
            }
        }
        
        this.hadLogged = function() {
            return model.hadLogged();
        }

        this.hasPermission = function(data) {
            var result =  controller.ajaxComSyncr("basic/HasPermission.do", data);
            return result;
        }
                        
        this.getConfig = function(data) {
                var cfg = controller.ajaxComSyncr("escritorio/RecoveryConfiguracion.do", data);
                //var cfg = this.controller.ajaxComSyncr("escritorio/RecoveryConfiguracionById.do", data);
                if (cfg && cfg.configuracion
                        && cfg.configuracion.length>0) cfg.configuracion = eval('('+cfg.configuracion+')');                           
                else return {configuracion:{}};                  
                return cfg;                    
        }
        
        this.setLanguage = function(languageKey) {
            model.setLanguage(languageKey);
            model.configureUI();
        }
        
        this.resetInterface = function() {
            view.reset();
            $("<div id='loadMainPage' class='kubbeLoadingBig'></div>").appendTo("body");
            controller.processEvent(controller.LOAD_I18N);
        }
        
        this.saveCookie = function(data) {
            model.saveCookie(data);
        }
        
        this.recoveryCookie = function(key) {
            return model.recoveryCookie(key);
        }   
        
        this.removeCookie = function(key) {
            if('loginsession'==key){
                controller.processEvent(controller.USER_STATUS_CHANGE);
            }
            model.removeCookie(key);
        }  
        
        
        
        this.saveConfig = function(data, page, direct) {
            controller.ajaxCom(URL_APL+"escritorio/SaveConfiguracion.do", true, data, direct);        
        }
        
        this.JsonSaveConfiguracion = function(data, page, direct) {
            if (direct.onsave) direct.onsave(data);
        }
        
        this.getLanguage = function() {
            var result =  model.getLanguageCode();
            return result;
        }
        
        this.addPage = function(data) {
            var numberPage = null;
            var api = model.getListenerDesktop();
            if (api) {
                var component = api.getComponent();
                if (component.ondesktop) numberPage = component.ondesktop("ADD_PAGE",data);
            }
            return numberPage;
        }
        
        this.closePage = function (data){            
            var api = model.getListenerDesktop();
            if (api) {
              var component = api.getComponent();              
              if (component.ondesktop) numberPage = component.ondesktop("CLOSE_PAGE",data);
            }
        }
        
        this.setListenerDesktop = function(API) {
            model.setListenerDesktop(API);
        }
        
        this.addKbox = function(data) {
            var api = model.getListenerDesktop();
            if (api) {
                var component = api.getComponent();
                if (component.ondesktop) numberPage = component.ondesktop("ADD_KBOX",data);
            }            
        }
        
        this.refreshPage = function() {
            var api = model.getListenerDesktop();
            if (api) {
                var component = api.getComponent();
                if (component.ondesktop) component.ondesktop("REFRESH_PAGE");
            }            
        }

        this.exit = function() {
            if (!DESKTOP_CONFIG_DEFAULT.exitAction || DESKTOP_CONFIG_DEFAULT.exitAction=="none") {
                DESKTOP.launchEvent(DESKTOP.RESET_INTERFACE);
            } else {
                location.href = DESKTOP_CONFIG_DEFAULT.exitAction
            }
        }
        this.loadInlineHelp = function (data){
            view.loadInlineHelp(data);
        }
        this.changeInlineHelp = function (data){
            view.changeInlineHelp(data);
        }
        this.getLanguageExt = function(){
            return model.getLanguageExt();
        }
        this.removeConfig = function(data){
            controller.ajaxCom(URL_APL+"escritorio/RemoveConfigByNameAction.do", true, {nameOrkboxId : data});
        }
    }    

    var controller = new Controller();
    controller.processEvent(controller.INIT, {});

    this.launchEvent = function(name, data, direct) {
        var result = controller.processEvent(name, data, null, direct);
        return result;
    }    
    this.GET_HAS_BULLETIN = controller.GET_HAS_BULLETIN;
    this.LOAD_GRAPHIC_UNIT = controller.LOAD_GRAPHIC_UNIT;
    this.GET_INFO_USER = controller.GET_INFO_USER;
    this.GET_USER_INFO = controller.GET_USER_INFO;
    this.ACTIVE_DIALOG = controller.ACTIVE_DIALOG;
    this.DESACTIVE_DIALOG = controller.DESACTIVE_DIALOG;
    this.SEND_MESSAGE = controller.SEND_MESSAGE;
    this.SEND_LOGIN = controller.SEND_LOGIN;
    this.GET_CONFIG = controller.GET_CONFIG;
    this.SAVE_CONFIG = controller.SAVE_CONFIG;
    this.SET_LANGUAGE = controller.SET_LANGUAGE;    
    this.RESET_INTERFACE = controller.RESET_INTERFACE;
    this.SAVE_COOKIE = controller.SAVE_COOKIE
    this.REMOVE_COOKIE = controller.REMOVE_COOKIE;
    this.RECOVERY_COOKIE = controller.RECOVERY_COOKIE;
    this.SAVE_CONFIG = controller.SAVE_CONFIG;
    this.GET_INFO_MODULE = controller.GET_INFO_MODULE;
    this.GET_LANGUAGE = controller.GET_LANGUAGE;
    this.ADD_PAGE = controller.ADD_PAGE;
    this.CLOSE_PAGE = controller.CLOSE_PAGE;
    this.SET_LISTENER_DESKTOP = controller.SET_LISTENER_DESKTOP;
    this.ADD_KBOX = controller.ADD_KBOX;
    this.HAS_PERMISSION = controller.HAS_PERMISSION;
    this.RESET_INFO = controller.RESET_INFO;
    this.IS_I18N = controller.IS_I18N;
    this.USER_STATUS_CHANGE = controller.USER_STATUS_CHANGE;
    this.HAD_LOGGED = controller.HAD_LOGGED;
    this.REFRESH_PAGE = controller.REFRESH_PAGE;
    this.GET_COMPANY_CONFIG_PARAM = controller.GET_COMPANY_CONFIG_PARAM;
    this.EXIT = controller.EXIT;
    this.LOAD_IN_LINE_HELP = controller.LOAD_IN_LINE_HELP;
    this.CHANGE_IN_LINE_HELP = controller.CHANGE_IN_LINE_HELP;
    this.GET_LANGUAGE_EXT = controller.GET_LANGUAGE_EXT;
    this.REMOVE_CONFIG = controller.REMOVE_CONFIG;
    this.FIND_BULLETIN_CONTENT = controller.FIND_BULLETIN_CONTENT;
    this.INIT = controller.INIT;
}

var DESKTOP = new Desktop();


