﻿var MV = window.MV = {};

MV.Util =
{
    NotEmpty: function(val) {
        if (val == undefined) { return false; }
        if (typeof (val) == 'number') { return true; }
        return (val != '');
    },
    Empty: function(val) { return !this.NotEmpty(val); },
    BlockUI: function(message, selector, opts) {
        if (!$.blockUI) { return; }
		var opt = Config.BlockUI.Options;
		    opt.message = Config.BlockUI.MessageTemplate.replace(/%%message%%/gi, (message) ? message.replace(/\s+/gi, '&nbsp;') : Config.BlockUI.LoadingMessage);
			opt = $.extend(true,opt,opts);
        if (!selector) {
            $.blockUI(opt);
            MV.Util.WindowResize();
        } else {
            $(selector).block(opt);
        }
    },
    WindowResize : function() {
        if (!$.blockUI) { return; }
        var l = (parseInt($(window).width()/2) - (parseInt(Config.BlockUI.Options.css.width.replace(/[^0-9]*/gi,''))/2)) + 'px';
        Config.BlockUI.Options.left = l;
        $('div.blockPage').css('left',l);
    },    
    UnBlockUI: function(selector) {
        if (!$.unblockUI) { return; }
        if($(selector)){
        	$(selector).unblock();
        }else{
	        $.unblockUI();
	    }
    },
    BindDropDown: function(selector, data, firstOption) {
        var $dd = $(selector).get(0);
        $dd.options.length = 0;
        var x = $dd.options.length;
        if (firstOption) {
            var fo = document.createElement("option");
            fo.text = firstOption;
            fo.value = '0';
            $dd.options[x++] = fo;
        }

        for (var i = 0; i < data.length; i++) {
            var option = document.createElement("option");
            option.text = data[i].Name || data[i].Key || data[i];
            option.value = data[i].Id || data[i];
            $dd.options[x++] = option;
        }
        return $(selector);
    }
}
$(window).resize(MV.Util.WindowResize);

MV.Logging={Log:null,Debug:null,Info:null,Warn:null,Error:null,Assert:null,Dir:null,DirXml:null,Trace:null,Group:null,GroupEnd:null,Time:null,TimeEnd:null,Profile:null,ProfileEnd:null,Count:null};
for(var o in MV.Logging) { MV.Logging[o]=function(){};}

MV.Queue = {
    Q: {},
    Add: function() {
        var name = arguments[0];
        var arr = this.Q[name] || [];
        arr.push({ fn: arguments[1], args: [].splice.call(arguments, 2, arguments.length - 1) });
        this.Q[name] = arr;
    },
    AddWithCallback: function() {
        var name = arguments[0];
        var arr = this.Q[name] || [];
        arr.push({ fn: arguments[1], args: [].splice.call(arguments, 2, arguments.length), callback: arguments[arguments.length - 1] });
        this.Q[name] = arr;
    },
    Execute: function(name, msFirst, ms, rev, callback) {
        if (callback) { this.Q[name].CallBack = callback; }
        var arr = this.Q[name] || [];
        if (!rev) { arr.reverse(); }
        if (arr.length > 0) {
            var o = arr.pop();
            window.setTimeout(function() { o.fn.apply(this, o.args); if (o.callback) { o.callback(); } else { MV.Queue.Execute(name, ms, ms, true); } }, msFirst);
        } else if (this.Q[name].CallBack) {
            this.Q[name].CallBack();
            this.Q[name] = null;
        }
    }
};

MV.Page =
{
    Name: "Default",
    LoadingMessage: Config.BlockUI.LoadingMessage,
    LoadStrings: true,

    Template_Loaded: function() { },
    Content_Loaded: function() { },
    Setup_Complete: function() { },

    Setup: function() {
        if (Config.Page_BeforeLoad) { Config.Page_BeforeLoad(MV.Page.Name); }
        MV.Util.BlockUI(MV.Page.LoadingMessage);
        $(Config.SiteTemplate.TemplateContainerId).hide();
        MV.Page.LoadTemplate(function() {
            $(Config.SiteTemplate.TemplateContainerId).show();
            $(Config.SiteTemplate.ContentContainerId).hide();
            MV.Page.LoadContent(function() {
                MV.Page.LoadStringsForPage(function() {
                    if (Config.Page_Loaded) { Config.Page_Loaded(MV.Page.Name); }
                    if (MV.Page.Setup_Complete) { MV.Page.Setup_Complete(); }
                });
            });
        });
    },

    LoadTemplate: function(callback) {
        MV.Page.GetFile('html', Config.SiteTemplate.URL, function(html) {
            $(Config.SiteTemplate.TemplateContainerId).append(html);
            if (MV.Page.Template_Loaded) { MV.Page.Template_Loaded(); }
            if (callback) { callback(); }
        });
    },

    LoadContent: function(callback) {
        MV.Page.GetFile('html', Config.Content.Location + '/' + MV.Page.Name.replace(/\s/gi, '_') + Config.Content.Extension, function(html) {
            $(Config.SiteTemplate.ContentContainerId).append(html);
            if (MV.Page.Content_Loaded) { MV.Page.Content_Loaded(); }
            if (callback) { callback(); }
        });
    },

    LoadStringsForPage: function(callback) {
        if (this.LoadStrings && !MV.WebServices.Strings) { if (callback) { callback(); } return; }
        MV.WebServices.Strings.LoadForPage(MV.Page.Name, callback);
    },

    Show: function() {
        MV.Util.UnBlockUI();
        $(Config.SiteTemplate.ContentContainerId).show();
    },

    RequireScript: function(script) {
        this.GetFile('script', script, null, false);
    },

    RequireCSS: function(cssfile, mediaType) {
        if (MV.Util.Empty(mediaType)) { mediaType = "screen"; }
        $("head").append('<link rel="stylesheet" href="' + cssfile + '" type="text/css" media="' + mediaType + '"/>');
    },

    GetFile: function(dataType, filename, callback, async) {
        $.ajax({ type: 'GET', url: filename, dataType: dataType, success: callback, cache: true, async: async });
    },

    Templates: {
        Add: function(templateName, selector, remove) {
            if (typeof selector == "string") { selector = $(selector); }
            MV.Page.Templates[templateName] = selector.clone(true).removeAttr('id');
            if (remove) { selector.remove(); }
            MV.Page.Templates[templateName].DataBind = function(obj) {
                MV.Page.Templates.DataBind(this, obj);
            };
            return MV.Page.Templates[templateName];
        },
        DataBind: function(template, obj) {
            for (var prop in obj) {
                //TODO: complete template data binding
                //camelcase className or add data-propname class to html
                var ditems = template.find("." + prop);
                // if typeof obj[prop] == object
                // MV.Page.Templates.DataBind(ditems, obj[prop] )
                ditems.text(obj[prop]);
            }
        }
    },

    HoverHelp: {
        HelpLoaded: {},
        Queue: {},
        AddToQueue: function(key) {
            var arr = [key];
            if (key.indexOf(',') > 0) { arr = key.split(','); }
            for (var i = 0; i < arr.length; i++) {
                this.Queue[arr[i].replace(/\s+/gi, '')] = true;
            }
        },
        Bind: function(scope) {
            var arr = [];
            for (var k in this.Queue) {
                arr[arr.length] = k;
            }
            if (arr.length > 0) {
                MV.WebServices.Strings.LoadHoverHelp(MV.Page.Name, arr, scope, MV.Page.HoverHelp.HoverHelp_Loaded);
            }
        },
        HoverHelp_Loaded: function(strings,scope,callback) {
            for (var tmpName in MV.Page.Templates) {
                MV.WebServices.Strings.BindTitles(MV.Page.Templates[tmpName], strings);
            }
            MV.WebServices.Strings.BindTitles(scope, strings);
            if (callback) { callback(strings); }
        },
        GetKeys: function(scope) {
            $(".hoverhelp", scope || $(document)).each(function() {
                var classes = $(this).attr('class').split(' ');

                for (var i = 0; i < classes.length; i++) {
                    if (classes[i] && classes[i].toLowerCase() != "hoverhelp" && classes[i].toLowerCase() != "string") {
                        MV.Page.HoverHelp.AddToQueue(classes[i]);
                    }
                }
            });
        }
    }
};

//WebServices
function BaseWebService() {

    this.Init = function(settings) {
        $.extend(this,settings);
    }

    this.GetResponseHandler = function(callback,responseHandler) {
        return (function(retObj) { if (callback) { callback(responseHandler(retObj)); } }); 
    };

    this.GetErrorHandler =  function(callback) {
        return (function(xhr, txt, err) {
                    if (xhr.responseText.indexOf("Authentication failed") > 0) { window.location = Config.ApplicationRoot; return; }
                    if (callback) { callback(); }   
                });
    };

    this.Call = function(options) 
    {
        //hacks in the old call arguments : MethodName, params[], callback ...
        if (arguments.length > 1)  { var fn = arguments[2]; var c = this.caller; options = {Method: arguments[0], Parameters: arguments[1], OnSuccess: function(){ var args=[true]; for(var i=0;i<arguments.length;i++) { args[args.length] = arguments[i]; } fn.apply(c, args); }}; }
        
        var opt = $.extend({ Method:null, Parameters:null, OnSuccess:null, OnError:null, BypassAuth:false, HandleResponse:null },options);
        if (MV.WebServices.Authentication && !opt.BypassAuth) 
        {
            var proxy = function(context,options) { opt.BypassAuth=true; return (function(){context.Call(options);}); }
            MV.WebServices.Authentication.CheckIfNeeded( proxy(this,opt) ); 
            return;
        }
      
        mv_ws_current_request = $.ajax({
            global      : false,
            type        : 'POST',
            dataType    : this.OutputDataType,
            contentType : this.ContentType,
            url         : this.FormatServiceCall(opt.Method),
            data        : this.FormatInputParameters(opt.Parameters) || '',
            success     : this.GetResponseHandler(opt.OnSuccess, opt.HandleResponse || this.HandleResponse),
            error       : this.GetErrorHandler(opt.OnError)
        });
    };
}

function DotNetWebService() {
    DotNetWebService.prototype.ContentType            = 'application/json',
    DotNetWebService.prototype.OutputDataType         = 'json',
    DotNetWebService.prototype.FormatServiceCall      = function(method) { return this.Location + "/" + method; };
    DotNetWebService.prototype.FormatInputParameters  = function(paramArray) {
        if (!paramArray) { return '{}'; }
        var retstr = "";
        for (var i = 0; i < paramArray.length; i += 2) {
            switch (typeof paramArray[i + 1]) {
                case "number":
                case "boolean":
                    retstr += '"' + paramArray[i] + '":' + paramArray[i + 1] + ',';
                    break;
                case "undefined":
                    retstr += '"' + paramArray[i] + '":null,';
                    break;
                default:
                    if (!paramArray[i + 1]) { retstr += '"' + paramArray[i] + '":null,'; }
                    else { retstr += '"' + paramArray[i] + '":"' + (paramArray[i + 1] + '').replace(/\\/g, '\\').replace(/\"/g, '\\"') + '",'; }
            }
        }
        if (retstr.length > 0) { retstr = retstr.substr(0, retstr.length - 1); } 
        return "{" + retstr + "}";
    },
    DotNetWebService.prototype.HandleResponse = function(response) {
        if (response.Message && response.Message == "Authentication failed.") { location = Config.ApplicationRoot; return null; }
        if (typeof response['d'] != 'undefined') { return response.d; }
        return response;
    }           
}
DotNetWebService.prototype = new BaseWebService();

function JavaWebService()
{
      JavaWebService.prototype.ContentType              = 'application/x-www-form-urlencoded';
      JavaWebService.prototype.OutputDataType           = 'json';
      JavaWebService.prototype.FormatServiceCall        = function(l, m) { return (l || this.Location) + '?action=' + m; };
      JavaWebService.prototype.FormatInputParameters    = function(paramArray)
      {      
            var retstr = '';
            for(var i=0; i < paramArray.length; i+=2) { retstr += paramArray[i] + "=" + paramArray[i+1] + '&'; }
            if (retstr.length > 0) { retstr = retstr.substr(0,retstr.length-1); } // chop off trailing &
            return retstr;
      };
	  JavaWebService.prototype.HandleResponse = function(response) 
	  {
		return response;
	  };
}
JavaWebService.prototype = new BaseWebService();

MV.WebServices =
{
    Add: function(name, scripturl, location, callback) {
        $.ajax({
            async: false,
            cache: true,
            type: "GET",
            url: scripturl,
            dataType: "script",
            success: function(){
                window[name].prototype = (Config.Platform.toLowerCase() == "java") ? new JavaWebService() : new DotNetWebService();
                MV.WebServices[name] = new window[name]({ Name: name, Location: location, ScriptLocation : scripturl });
                if (Config.WebService_Loaded) { Config.WebService_Loaded(MV.WebServices[name]); }
                if (callback) { callback( MV.WebServices[name] ); }
            }
        });
    }
};

$(document).ready(function() {
    Config.Application_Loaded();
    if (!MV.Page.DontSetup) { MV.Page.Setup(); }
});

jQuery.fn.extend({
    /**
    * Returns get parameters.
    * If the desired param does not exist, null will be returned
    * To get the document params:
    * @example value = $(document).getUrlParam("paramName");
    * To get the params of a html-attribut (uses src attribute)
    * @example value = $('#imgLink').getUrlParam("paramName");
    */
    getUrlParam: function(strParamName) {
        strParamName = escape(unescape(strParamName));
        var returnVal = new Array();
        var qString = null;
        if ($(this).attr("nodeName") == "#document") {
            if (window.location.search.search(strParamName) > -1) {
                qString = window.location.search.substr(1, window.location.search.length).split("&");
            }
        } else if ($(this).attr("src") != "undefined") {
            var strHref = $(this).attr("src")
            if (strHref.indexOf("?") > -1) {
                var strQueryString = strHref.substr(strHref.indexOf("?") + 1);
                qString = strQueryString.split("&");
            }
        } else if ($(this).attr("href") != "undefined") {
            var strHref = $(this).attr("href")
            if (strHref.indexOf("?") > -1) {
                var strQueryString = strHref.substr(strHref.indexOf("?") + 1);
                qString = strQueryString.split("&");
            }
        } else {
            return null;
        }
        if (qString == null) return null;
        for (var i = 0; i < qString.length; i++) {
            if (escape(unescape(qString[i].split("=")[0])) == strParamName) {
                returnVal.push(qString[i].split("=")[1]);
            }
        }
        if (returnVal.length == 0) return null;
        else if (returnVal.length == 1) return returnVal[0];
        else return returnVal;
    }
});