﻿(function($, window, undefined) {

    var alpEngine = {};

    /*Публикуем*/
    window.alpEngine = alpEngine;

    /*
    *	Устанавливает специфическую версию jQuery для всего модуля
    */
    alpEngine.setjQuery = function(jQueryObject) {
        $ = jQueryObject;
        alpEngine.jQuery = jQueryObject;
        alpEngine.$ = jQueryObject;
    }

    alpEngine.setjQuery(jQuery);  //по-умолчанию

    /*
    *	Загрузка страницы pageName в элемент container
    */
    alpEngine.loadPage = function(sectionName, pageName, container) {
        alpEngine.showProgressBar(container);

        //Загружаем вариацию движка текущей конфигруации (которого может и не быть)
        alpEngine.loadScript(sectionName + "/alpEngine.js");

        // loadRemoteConfig - функция может быть переопределена в загруженной вариации
        alpEngine.loadRemoteConfig(
            function() {
                if (!pageName) pageName = alpEngine.first(alpConfig.site[sectionName]);

                alpEngine.loadScript(sectionName + "/" + pageName + ".js");

                //Очищаем имя функции
                var functionName = new String(pageName).replace(/-/g, "");

                eval("alpEngine." + functionName + "Insert(alpEngine.jQuery, alpEngine, container);");
            });
    };


    /*
    *	Возращает ссылку на страницу сайта
    *   Все ссылки сайта обязательно пропускать через нее!!!
    */
    alpEngine.getSiteLink = function(sectionName, pageName, data, additionalData) {
        data = alpEngine.createParamsUrl(data, additionalData);
        var pageRoot = alpConfig.site[sectionName].root;
        return alpConfig.site.root + pageRoot + "?" + alpEngine.createParamsUrl({ pageName: pageName }) + data;
    };

    /*
    *	 Возращает ссылку (с доменом) на страницу сайта 
    */
    alpEngine.getSiteLinkWithDomain = function(sectionName, pageName, data, additionalData) {
        data = alpEngine.createParamsUrl(data, additionalData);
        var siteRoot = alpConfig.site.root.replace(new RegExp("^https?://[^/]+"), "");
        if (siteRoot && siteRoot.charAt(0) != "/") {
            siteRoot = "/" + siteRoot;
        }
        var pageRoot = alpConfig.site[sectionName].root;
        return "http://" + document.location.host + siteRoot + pageRoot + "?" + alpEngine.createParamsUrl({ pageName: pageName }) + data;
    }

    /*
    *	Заглушка для загрузки удаленного конфига
    */
    alpEngine.loadRemoteConfig = function(callback) {
        callback();
    };

    /*
    Функция получения данных с сервера
    requestUrl — Url запроса,
    successResponse — функция, вызываемая при успешной загрузке данных (не обязательно)
    errorResponse — функция, вызываемая при ошибке загрузки данных (не обязательно)
    */
    alpEngine.loadData = function(requestUrl, successResponse, errorResponse) {
        requestUrl = AppendSessionId(requestUrl);
        $.ajax({
            async: false,
            dataType: "jsonp",
            url: requestUrl,
            jsonp: "callback",
            error: function(data) {
                if (errorResponse != null) errorResponse(data);
            },
            success: function(data) {
                SetSessionId(data);
                if (successResponse != null) successResponse(data);
            },
            statusCode: {
                401: function() {
                    if (errorResponse != null) errorResponse({ statusCode: 401, message: "Невозможно получить доступ к серверу." });
                }
            }
        });
    };

    /*
    *	Добовляет идентификатор сессии к строке запроса
    */
    function AppendSessionId(requestUrl) {
        var sessionId = alpEngine.getCookie("AlpSessionId");
        if (sessionId != null && sessionId != "null") {
            var sessionParam = "/(X(1)S(" + sessionId + "))/";

            var index = Find(requestUrl, "/", 3);
            var baseAdress = requestUrl.substring(0, index);
            var paramsAdress = requestUrl.substr(index + 1);

            requestUrl = baseAdress + sessionParam + paramsAdress;
        }
        return requestUrl;
    };

    function Find(str, pattern, number) {
        var index = -1;
        for (var i = 0; i < number; i++) {
            index = str.indexOf(pattern, index + 1);
            if (index < 0) {
                break;
            };
        }
        return index;
    };

    /*
    *  Устанавливает текущее значение идентификатора сессии
    */
    function SetSessionId(data) {
        if (data && data.SessionId) {
            //if (alpEngine.getCookie("AlpSessionId") == undefined) {
            alpEngine.setCookie("AlpSessionId", data.SessionId, null, "/");
            //};
        };
    };

    /*
    *	Установка значения
    */
    alpEngine.setCookie = function(name, value, expires, path, domain, secure) {
        document.cookie = name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
    };

    /*
    *	Получение значения
    */
    alpEngine.getCookie = function(name) {
        var cookie = " " + document.cookie;
        var search = " " + name + "=";
        var setStr = null;
        var offset = 0;
        var end = 0;
        if (cookie.length > 0) {
            offset = cookie.indexOf(search);
            if (offset != -1) {
                offset += search.length;
                end = cookie.indexOf(";", offset);
                if (end == -1) {
                    end = cookie.length;
                }
                setStr = unescape(cookie.substring(offset, end));
            };
        };
        return (setStr);
    };


    /*
    Функция загрузки шаблона с сервера
    name — название шаблона
    url — адрес шаблона относительно папки шаблонов,
    */
    alpEngine.loadTemplate = function(url, name) {
        if ($.template[name] != undefined)
            return;
        url = alpConfig.dataRoot + ("templates/" + url) + "?v=" + alpEngine.version;
        return $.ajax({
            async: false,
            dataType: "html",
            url: url,
            error: function(data) { alert("Невозможно загрузить шаблон " + url); },
            success: function(data) { $.template(name, data); }
        });
    };

    /*
    Загружает шаблоны из html файла имеющего формат:    
    имя_шаблона_1|
    html_шаблона
    %TEMPLATE_DELIMITER%
    имя_шаблона_2|
    html_шаблона
    %TEMPLATE_DELIMITER%    
    ...
    url — адрес html файла
    */
    alpEngine.loadTemplates = function(url) {
        url = alpConfig.dataRoot + ("templates/" + url) + "?v=" + alpEngine.version;
        return $.ajax({
            async: false,
            dataType: "text",
            url: url,
            error: function(data) { alert("Невозможно загрузить шаблон " + url); },
            success: function(str) {
                /*$("[id$='-template-container']", data).each(function(index, element) {
                $.template($(element).attr("id").replace("-template-container", ""), $(element));
                });*/
                var tmpls = str.split("%TEMPLATE_DELIMITER%");
                for (var i = 0; i < tmpls.length; i++) {
                    var tmpl = tmpls[i];
                    var nameEndIndex = tmpl.indexOf("|");
                    var tmplName = tmpl.substring(0, nameEndIndex);
                    tmpl = tmpl.substring(nameEndIndex + 1);
                    $.template($.trim(tmplName), tmpl);
                }
            }
        });
    }

    /*
    *	Накладывает данные на шаблон, результат вставляет в конечноый элемент
    *  
    *  elements — элемент(ы), к которым применяется шаблон
    *  templateName — имя скомпилированного шаблона
    *  data — основные данные
    *  additionalData — дополнительные данные
    */
    alpEngine.insertTemplate = function(elements, templateName, data, additionalData) {
        elements.empty();
        $.tmpl(templateName, data, additionalData).appendTo(elements);
    };

    /*
    *	Синхронная загрузка скрипта 
    */
    alpEngine.loadScript = function(url) {
        url = alpConfig.dataRoot + ("scripts/" + url) + "?v=" + alpEngine.version;
        $.ajax({
            async: false,
            url: url,
            cache: true,
            dataType: 'script'
        });
    };

    /*
    *	Загрузка стиля
    */
    alpEngine.loadCss = function(url) {
        url = alpConfig.dataRoot + ("content/design/" + url);

        var css = document.createElement('link');
        css.setAttribute('type', 'text/css');
        css.setAttribute('rel', 'stylesheet');
        css.setAttribute('href', url);
        var head = document.getElementsByTagName('head').item(0);
        head.insertBefore(css, head.firstChild);
        return css;
    };

    /*
    *	Перенаправление по ссылке
    */
    alpEngine.goTo = function(sectionName, pageName, data, additionalData) {
        var url = alpEngine.getSiteLink(sectionName, pageName, data, additionalData);
        document.location = url;
        return false;
    };

    /*
    *	Функция проверки на наличие ошибок
    */
    alpEngine.checkError = function(data, errorHandler) {
        if (data.Error != undefined && data.Error.IsError) {
            if (errorHandler != null) {
                errorHandler(data.Error);
            };
            return false;
        };
        return true;
    };

    /*
    *	Заполнение ссылок. Функция подменяет изначальное значение аттрибута href, значением url
    */
    alpEngine.fillLink = function(name, sectionName, pageName, data, additionalData) {
        var url = alpEngine.getSiteLink(sectionName, pageName, data, additionalData);
        alpEngine.fillOutsideLink(name, url);
    };

    alpEngine.fillOutsideLink = function(name, url) {
        var links = $('a[href="' + name + '"]');

        //Для любимого эксплорера (6&7):
        links = $.merge(links, $('a[nameProp="' + name + '"]'));

        links.attr("href", url);

        links.filter("[splash]").click(function() {
            alpEngine.showInSplash(this.href);
            return false;
        });
    };

    // Возращает строчку параметров из переданных. Если объект равен empty - берет значение из текущей страницы
    alpEngine.createParamsUrl = function(params, additinalParamsUrl) {
        var paramUrl = "";
        for (paramName in params) {
            var paramVal = params[paramName];
            if (paramVal == null) {
                paramVal = alpEngine.getParam(paramName);
            }
            paramUrl += paramName + "=" + encodeURIComponent(paramVal) + "&";
        }
        return paramUrl + (additinalParamsUrl != null ? additinalParamsUrl : "");
    };

    // возвращает значение параметра из url по имени
    alpEngine.getParam = function getParam(paramName) {
        var params = location.search.substring(1).split("&");
        // отсекаем "?" и вносим переменные и их значения в массив 
        var variable = "";
        for (var i = 0; i < params.length; i++) {
            // пробегаем весь массив 
            if (params[i].split("=")[0] == paramName) { // если это искомая переменная 
                // если значение параметра задано, то возвращаем его 
                if (params[i].split("=").length > 1) variable = params[i].split("=")[1];
                return variable;
            }
        }
        return "";
    };


    // Приведение даты в формате JSON к виду format
    alpEngine.formatDate = function(dateJson, format) {
        if (dateJson == "" || dateJson == null) {
            return "";
        }
        return $.format(alpEngine.getDate(dateJson), format, "ru");
    };

    // Приведение даты в формате JSON к объекту Date
    alpEngine.getDate = function(dateJson) {
        if (dateJson == "" || dateJson == null) {
            return null;
        }

        var signIndex = dateJson.indexOf("+");
        if (signIndex == -1) {
            signIndex = dateJson.indexOf("-")
        }

        if (signIndex == -1) {
            return new Date(parseInt(dateJson.substr(6)));
        }
        else {
            var localDateMilliSec = parseInt(dateJson.substring(6, signIndex));

            /*Код, компенсирующий разницу во времени между клиентом и сервером*/
            var currentTimeZoneOffsetInHours = -(new Date(localDateMilliSec)).getTimezoneOffset() / 60;

            var timeZoneOffsetHours = dateJson.substring(signIndex + 1, signIndex + 3);
            var timeZoneOffsetMinutes = dateJson.substring(signIndex + 3, signIndex + 5);

            var hours = parseInt(timeZoneOffsetHours) - currentTimeZoneOffsetInHours;
            var minutes = parseInt(timeZoneOffsetMinutes);
            var inc = (hours * 60 + minutes) * 1000 * 60;

            return new Date(localDateMilliSec + inc);
        }
    };

    // Приведение времени в формате  [-][d.]hh:mm:ss[.fffffff] к виду HHч mmмин
    alpEngine.formatTime = function formatTime(dateJson) {
        var daysToHours = 0;

        var arr = dateJson.split(".");
        if (arr.length > 1) {
            daysToHours = parseInt(arr[0]) * 24;
            return ((parseInt(arr[1].split(":")[0], 10) + daysToHours) + "ч " + parseInt(arr[1].split(":")[1], 10) + "мин");
        }
        else
            return (parseInt((arr[0].split(":"))[0], 10) + "ч " + parseInt((arr[0].split(":"))[1], 10) + "мин");
    };

    alpEngine.formatPrice = function(price) {
        if (null != price) {
            if ((typeof price === typeof 1) && isFinite(price)) {
                return price.toFixed(2);
            }
            else if (price.Currency && price.Value != null) {
                return price.Value.toFixed(2) + " " + price.Currency.Name;
            }
            else {
                return price;
            }
        }
        else return price;
    };


    alpEngine.first = function(array) {
        for (var i in array) return array[i];
    };

    alpEngine.getArrayItemSafe = function(array, index, prop, defaultValue) {
        if (array != undefined && array[index] != undefined) {
            if (prop != undefined) {
                return array[index][prop] != undefined ? array[index][prop] : defaultValue;
            }
            else
                return array[index];
        }
        else return defaultValue;
    }

    // Выбирает существительное с правильным окончанием в зависимости от числа number
    alpEngine.language = {};

    alpEngine.language.getNoun = function(number, one, two, five) {
        number = Math.abs(number);
        number %= 100;
        if (number >= 5 && number <= 20) {
            return five;
        }
        number %= 10;
        if (number == 1) {
            return one;
        }
        if (number >= 2 && number <= 4) {
            return two;
        }
        return five;
    };

    alpEngine.language.getAdj = function(number, one, two) {
        number = Math.abs(number);
        number %= 100;
        if (number == 11) return two;
        number %= 10;
        if (number == 1) return one;
        return two;
    };

    alpEngine.designEventBinders = {};

    alpEngine.updateDesignEvents = function() {
        for (var binding in alpEngine.designEventBinders) {
            alpEngine.designEventBinders[binding]();
        };
    };

    /*
    *	Показывает прогресбар в заданном элементе
    */
    alpEngine.showProgressBar = function(container) {
        //реализуется конкретным модулем
    };

    /*
    *	Скрывает прогресбар в заданном элементе
    */
    alpEngine.hideProgressBar = function(container) {
        //реализуется конкретным модулем
    };

    var initialized = false;
    
    /*
    *	Инициализация движка
    *   Обязательно вызывать перед любой опреацией!
    */
    alpEngine.initialize = function(configPath) {
        if (initialized) {
            return false;
        };

        var initializeCore = function() {
            /*Основные скрипты*/
            alpEngine.loadScript("jquery/jquery.tmpl.min.js");
            alpEngine.loadScript("jquery/globalization/jquery.glob.min.js");
            alpEngine.loadScript("jquery/globalization/jquery.glob.ru.min.js");
            alpEngine.loadScript("commons/Math.uuid.js");
            if (typeof swfobject == "undefined") {
                alpEngine.loadScript("commons/swfobject.min.js");
            }

            /*Стили*/
            alpEngine.loadCss("main.css");

            alpEngine.loadScript("commons/design.js");
            alpEngine.loadScript("commons/splash.js");

            initialized = true;
            return initialized;
        };

        if (window.alpConfig) {
            return initializeCore();
        }

        if (!configPath) {
            configPath = "config.js";
        }

        /*Загружаем основной конфиг*/
        $.ajax({
            async: false,
            url: configPath,
            context: document.head,
            cache: false,
            dataType: 'script',
            success: function(data) {
                /*Для света моих очей, Эксплорера:*/
                if (!window.alpConfig) eval(data);

                return initializeCore();
            }
        });
    };

    // Версия модуля
    alpEngine.version = 1.077;

})(jQuery, window);


