/**
 * @abstract Набор функций для работы с регионами
**/

/** Код айдишников выбранных/отчекнутых регионов, например __regionsCode = "255, -40, -30, 35" */
var __regionsCode = "";

/**
 * Дерево регионов. Имеет вид:
 * tree[objRegionA.RegionId] == objRegionA
*/
var RegionsTree = new Array();


/**
 * Конструктор инстансов объектов типа objRegion
 */
function objGetRegion()
{
        var inst = new Object();
        
        inst.Id = getObjUniqueId();
        Objects[inst.Id] = inst;
        
        inst.RegionId = -1;
        inst.Name = "Новый регион";
        inst.ParentRegionId = null;
        inst.getChildRegions = function() // STUB эту штуку можно аггрегировать с помощзью RebuildRegionsTree
        {
                var retRegions = new Array();
                for (x in RegionsTree)
                {
                        var reg = RegionsTree[x];
                        //alert(inst.Name + ".ParentRegionId == " + reg.ParentRegionId + "\r\n" + "child: " + reg.Name + "()");
                        if (reg.ParentRegionId == inst.RegionId)
                        {
                                retRegions[reg.RegionId] = reg;
                                //alert(inst.Name + " child: " + reg.Name);
                        }
                }
                return retRegions;
        }
        
        inst.Checked = function() // STUB это тоже можно аггрегировать
        {
                return this.jq().attr("checked");
        } 
        
        inst.setId = function (sId)
        {
                inst.RegionId = sId;
        }
        inst.setName = function(sName)
        {
                inst.Name = sName;
        }
        inst.setParentId = function (sId)
        {
                inst.ParentRegionId = sId;
        }
        
        inst.ToString = function()
        {
                return inst.Name + " (Id: " + inst.RegionId + ", parentId: " + inst.ParentRegionId + ")";
        }
        
        // STUB STUB10src
        // STUB эта шняга формальна, чтобы был непустой .jq. Вообще ее надо оставить, но обязательно добавить что-то вроде jqRefreshGUI, который вызывать из всех сетеров объекта
        // STUB Сейчас эта штука доблируется в некоторых местах, где отмечена как STUB10. Оттуда убрать, оставить ссылку на .jq.html().
        var code = '<input type="checkbox" id="' + inst.RegionId + '" />' +
                                                '<label for="' + inst.RegionId + '">' +
                                                        inst.Name +
                                                '</label>';
                                                
        // STUB а вот сейчас я решил изъебнуться - jq впервые будет гетером
        inst.jq = function()
        {
                var jq = $('#' + inst.RegionId + '');
                return jq;
        }
        
        return inst;
}


/**
 * Отправляет серверу запрос о получении регионов via XEP.
 * В случае успешного прохождения запроса, вызывает указанный калбэк.
 * @argument succCallback {pointer} калбек, дергаемый в случае успешного прохождения запроса к серверу
 */
function beginLoadRegions(succCallback)
{
        var xep = objGetXEPRequest();
        xep.AddPart(XEPGetRegions);
        xep.Perform (function (response)
        {
                // WIN
                if (response.Status == soapStatusOK)
                {
                        setStatus("Данные получены от сервера, начинаем парсить");
                        if (response.TheOnlyPart == null)
                        {
                                alert("Ошибка получения списка регионов: не найден обязательный парт");
                                setStatus("Ошибка получения списка регионов: не найден обязательный парт");
                                return;
                        }

                        var part = response.TheOnlyPart;
                        if (part.Status == soapStatusOK)
                        {
                                RegionsClear();
                                for (x in part.Results)
                                {
                                        var result = part.Results[x];
                                        var regionId = result["id"];
                                        var regionParentId = result["parentId"];
                                        var regionName = result["name"];
                                        var objRegion = objGetRegion();
                                        objRegion.setId(regionId);
                                        objRegion.setName(regionName);
                                        objRegion.setParentId(regionParentId);
                                        RegionAdd(objRegion);
                                }
                                setStatus("Регионы успешно загружены и распарсены");
                                succCallback();
                        }
                        else
                        {
                                alert("Ошибка получения регионов от сервера: " + part.StatusMessage);
                                setStatus("Ошибка получения регионов от сервера: " + part.StatusMessage);
                        }
                }
                else
                {
                        alert ("Ошибка получения регионов от сервера: " + response.StatusMessage);
                        setStatus("Ошибка получения регионов от сервера: " + response.StatusMessage);
                }
        },
        function (obj, msg)
        {
                // FAIL
                alert("Ошибка получения регионов от сервера");
                setStatus("Ошибка получения регионов от сервера");
        });
}

// STUB RegionsClear, RegionAdd и пр. = все этьо потом обернуть в колекцию регионов

/**
 * Очищает дерево регионов RegionsTree
 */
function RegionsClear()
{
        RegionsTree = new Array();
}

/**
 * Добавляет регион в дерево регионов RegionsTree
 * @argument objRegion {objRegion} Объект типа objRegion
 */
function RegionAdd (objRegion)
{
        //alert(objRegion.RegionId + ":" + objRegion.Name + ":" + objRegion.ParentRegionId);
        RegionsTree[objRegion.RegionId] = objRegion;
        /* Кусок для случая, когда дерево регионов RegionsTree имеет древовидную структуру согласно вложенности регионов
           Подобный кусок, при необходимости, нужно вставить в GetRegion и другие методы, ибо там ничего подобного не учтено
        if ((objRegion.ParentRegionId == null) || (objRegion.ParentRegionId < 1))
        {
                RegionsTree[objRegion.RegionId][0] = objRegion;
        }
        else
        {
                RegionsTree[objRegion.ParentRegionId][objRegion.RegionId] = objRegion;
        }
        */
}

/**
 * Отдает регион по айдишнику
 * @argument sId {string} Айдишник искомого региона
 */
function GetRegion(sId)
{
        return RegionsTree[sId];
}

/**
 * Возвращает массив регионов вида arr[objRegion.RegionId] == objRegion, не имеющих родительских регионов
 */
function GetHighLevelRegions()
{
        var retRegions = new Array();
        for (x in RegionsTree)
        {
                var objRegion = RegionsTree[x];
                if ((objRegion.ParentRegionId == null) || (objRegion.ParentRegionId < 0))
                {
                        retRegions[objRegion.RegionId] = objRegion;
                }
        }
        return retRegions;
}


function asSize(obj)
{
        var i = 0;
        for (x in obj)
        {
                i++;
        }
        return i;
}

var CheckedRegions = new Object;
function UpdateCheckedRegionsList()
{

        CheckedRegions = new Object();

        CheckedRegions = getRegionsChecked();

        var retString = "";

        for (x in CheckedRegions)
        {
                var obj = CheckedRegions[x];
                retString += obj.ToString();
                retString += "\r\n";
        }
}

function UpdateCheckedRegionsListGUI()
{
        for (x in CheckedRegions)
        {
                var region = CheckedRegions[x];
                CheckRegionById(x);
        }
}
function getRegionsChecked()
{

        var arrRegions = new Object();
        
        for (x in RegionsTree)
        {
        
                var objRegion = RegionsTree[x];
        
                var jqReg = objRegion.jq();
                if (jqReg.attr('checked')== true)
                {
        
                      arrRegions[objRegion.RegionId] = objRegion;
        
                }
        }
        return arrRegions;
}




function tree(expander)
{
        $(expander).click(function()
        {
                $(expander).hasClass('collapsed') ? openTree(this) : closeTree(this) ;
        })
}

function openTree(expander)
{
        //alert('opentree');
        $(expander).addClass('expanded');
        $(expander).removeClass('collapsed');
        $(expander).parents('li').eq(0).children('ul').css(
        {
                display:'block'
        });
}

function closeTree(expander)
{
        $(expander).removeClass('expanded');
        $(expander).addClass('collapsed');
        $(expander).parents('li').eq(0).children('ul').css(
        {
                display:'none'
        });
}

function drawRegions(sNewRegionsCode)
{
        var hlRegions = GetHighLevelRegions();
        var retString = "";
        
        retString +=    '<div class="regions-choice-container" id="regions_dialog">' + "\r\n" +
                                '<div class="regions-choice-holder">' + "\r\n" +
                                        '<div class="regions-choice-wrap">' + "\r\n" +
                                        '<div class="regions-choice">' + "\r\n" +
                                        '<p>' + "\r\n" +
                                            'Для повышения эффективности рекламы вы можете уточнить регион показов объявлений. После выбора региона, статистика показов будет отражаться только по нему.' + "\r\n" +
                                        '</p>' + "\r\n" +
                                        '<div class="city-choice-wrap">' + "\r\n" +
                                            //'<form action="">' + "\r\n" +
                                                '<div class="fast-city-choice">' + "\r\n" +
                                                    'Быстрый выбор:' + "\r\n" +
                                                    '<div>' + "\r\n" +
                                                        '<a href="#" onclick="CheckRegionById(1, true); return false;">Москва и область</a>,' + "\r\n" +
                                                    '</div>' + "\r\n" +
                                                    '<div>' + "\r\n" +
                                                        '<a href="#" onclick="CheckRegionById(2, true); return false;">Санкт-Петербург</a>' + "\r\n" +
                                                    '</div>' + "\r\n" +
                                                '</div>' + "\r\n" +
                                                '<p>' + "\r\n" +
                                                    '<input type="button" class="button submit-button" value="Выбрать" onclick="dialogRegionsClose(true);" />' + "\r\n" +
                                                    '<input type="button" class="button reset-button" value="Очистить" onclick="dialogRegionsClearSelectedRegions();" />' + "\r\n" +
                                                '</p>' + "\r\n" +
                                                '<ul class="regions-tree" id="regions-tree">' + "\r\n";
        for (x in hlRegions)
        {
           var objRegion = hlRegions[x];
           retString += GetBranchHTML(objRegion);
        }
        
        retString +=                    '<p>' + "\r\n" +
                                                '<input type="button" class="button submit-button" value="Выбрать" onclick="dialogRegionsClose(true);" />' + "\r\n" +
                                                '<input type="button" type="reset" class="button reset-button" value="Очистить" onclick="dialogRegionsClearSelectedRegions();" />' + "\r\n" +
                                                '</p>' + "\r\n" +
                                        //'</form>' + "\r\n" +
                                        '<div id="regionsTempResult"></div>' +
                                        '</div>' + "\r\n" +
                                '</div>' + "\r\n" +
                                '</div>' + "\r\n" +
                        '</div>' + "\r\n" +
                        '</div>' + "\r\n" ;
        $(retString).appendTo('body');
        
        $('#regions_dialog').dialog(
        {
                modal: true,
                width:700,
                height:'auto',
                position:'center',
                title:'Выбор регионов',
                close: function()
                {
                        $("#regions_dialog").remove();
                },
                resizable:false
        });
        
        $('#regions-tree .expander').each(function()
        {
                tree(this);
                $(this).siblings('input').eq(0).click(function()
                {
                        var inputParent = $(this).parents('li').eq(0);

                        if($(this).attr('checked') == true)
                        {
                                openTree($(this).siblings('.expander'));

                                $(':checkbox',inputParent).not($(this)).attr('checked',true);

                                var targetInput2 = $(this).parents('ul').eq(0);
                                var targetInput = $(this).parents('ul').eq(0).prev('div');

                                var hui = true;
                                $(':checkbox', targetInput2).each(function() // STUB насчет пиздатости этой конструкции имеются сомнения :)
                                {
                                        if ($(this).attr('checked') == false)
                                        {
                                                hui = false;
                                        }
                                })
                                if (hui == true)
                                {
                                        $(':checkbox', targetInput).attr('checked', true);
                                }
                                else
                                {
                                }
                        }
                        else
                        {
                                $(':checkbox',inputParent).not($(this)).attr('checked',false);

                                var targetInput2 = $(this).parents('ul').eq(0);
                                var targetInput = $(this).parents('ul').eq(0).prev('div');
                                
                                var hui = false;
                                $(':checkbox', targetInput2).each(function() // STUB насчет пиздатости этой конструкции имеются сомнения :)
                                {
                                        if ($(this).attr('checked') == true)
                                        {
                                        hui = true;
                                        }
                                })
                                if (hui == false)
                                {
                                       $(':checkbox', targetInput).attr('checked', false);
                                }
                        }
                });
        });

        $('.regions-choice-closer').click(function()
        {
                dialogRegionsClose();
                SetRegionsDialogLinkAnchor(RegionsCode2String(__regionsCode));
        })
        
        //alert(sNewRegionsCode);
        if (sNewRegionsCode != null)
        {
                __regionsCode = sNewRegionsCode;
                if (sNewRegionsCode.length > 0)
                {
                        var arrRegions = __regionsCode.split(",");
                        for (x in arrRegions)
                        {
                                var sRegionId = arrRegions[x]; // Может быть с предшествующим минусом
                                if (sRegionId[0] != "-")
                                {
                                        sRegionId = sRegionId.replace("-", "");
                                        CheckRegionById(sRegionId);
                                }
                        }
                        for (x in arrRegions)
                        {
                                var sRegionId = arrRegions[x]; // Может быть с предшествующим минусом
                                if (sRegionId[0] == "-")
                                {
                                        sRegionId = sRegionId.replace("-", "");
                                        UncheckRegionById(sRegionId);
                                }
                        }
                }
                else
                {
                        for (x in GetHighLevelRegions())
                        {
                                var region = RegionsTree[x];
                                UncheckRegionById(region);
                        }
                }
        }
        SetRegionsDialogLinkAnchor(RegionsCode2String(__regionsCode));
}

function RegionsCode2String(regions, cut)
{
		cut = ( cut == undefined || cut !== false ) ? true : false ;
		
        if (__regionsCode.length < 1)
                return "Все";
        var arrRegions = __regionsCode.split(",");
        var retString = "";
        var bExceptions = false;
        for (x in arrRegions)
        {
                var sRegionId = arrRegions[x]; // Может быть с предшествующим минусом
                if (sRegionId[0] == "-")
                {
                        var s = RegionsTree[sRegionId.replace("-", "")].Name;
                        if (bExceptions == false)
                        {
                                retString += " (кроме: "; // STUB этот пиздец с запятыми неизлечим пока регионы вообще формируются подобной строкой, вместо внятной коллекции или перелинкованных массивов
                                retString += s;
                                bExceptions = true;
                        }
                        else
                        {
                                retString += "," + s;
                        }
                }
                else
                {
                        if (bExceptions == true)
                        {
                                bExceptions = false;
                                retString += ")";
                        }
                        retString += "," + RegionsTree[sRegionId].Name;
                        
                }
        }
        if (bExceptions == true)
        {
                retString+=")";
        }
        retString = retString.replace(/^,/g, "");
        
        if (cut && retString.length >= 75)
        {
                retString = retString.slice(0, 71) + "...";
        }

        return retString;
}

function SetRegionsDialogLinkAnchor(sAnchor) // STUB убрать из этого файла
{
        if (sAnchor.length>0)
        {
                $('#checkedRegionsLabel').text(sAnchor);
        }
}

function GetRegionsDialogLinkAnchor() // STUB копипаст
{
        return $('#checkedRegionsLabel').text();
}

/** Возвращает строку с айдишниками, в которой закодировано состояние выбранных/анчекнутых регионов (по образцу __regionsCode) */
function GetRegionsCode() 
{
        var regions = GetHighLevelRegions();
                        
        var retString = "";
        for (x in regions)
        {
                var region = regions[x];
                var s = GetRegionDirectUrlCode(region, false, null); // STUB эта часть полностью повторяет кусок из GetRegionDirectUrlCode. Отрефакторить. В идеале вообще оперировать массивами, которые потом имплодить, а то пиздец какой-то нубский.
                if (s.length>0)
                {
                        retString += "," + s;
                }
                retString = retString.replace(/^,/g, "");
        }
        return trim(retString);
}

/**
 * Чекает регион в гуе
 * @argument RegionId {string} идентификатор региона
 * @argument bAutoOpenNodes {bool} открывать ли ноду зачекнутого региона
 */
function CheckRegionById(RegionId, bAutoOpenNodes)
{
        if (bAutoOpenNodes!=true)
        {
                bAutoOpenNodes = false;
        }
        if (($('#' + RegionId).attr('checked') == null) || ($('#' + RegionId).attr('checked') == false))
        {
                $('#' + RegionId).attr('checked', true); // STUB хакэраунд ололо
                $('#' + RegionId).click();
                $('#' + RegionId).attr('checked', true); // STUB хакэраунд ололо
         
                if (bAutoOpenNodes == true)
                {
                        $('#' + RegionId).parents('.qqq').each(function()
                        {
                                $(this).children('div').children('input').each(function(){ openTree($(this).siblings('.expander')); });
                        });
                }
        }
}

/**
 * Анчекает регион в гуе
 * @argument RegionId {string} идентификатор региона
 */
function UncheckRegionById(RegionId)
{
        if ($('#' + RegionId).attr('checked') == true)
        {
                $('#' + RegionId).attr('checked', false); // STUB хакэраунд ололо
                $('#' + RegionId).click();
                $('#' + RegionId).attr('checked', false); // STUB хакэраунд ололо         
        }
}

function GetRegionDirectUrlCode(objRegion, bSomeonesChild, bParentChecked)
{
        var retString = "";
        var childs = objRegion.getChildRegions();
        if (bSomeonesChild == true)
        {
                if ((bParentChecked == true) && (objRegion.Checked() == false))
                {
                        retString += ",-" + objRegion.RegionId;
                }
                else
                {
                        if ((bParentChecked == false) && (objRegion.Checked() == true))
                        {
                                retString += objRegion.RegionId;
                        }
                }
        }
        else
        {
                if (objRegion.Checked() == true)
                {
                        retString += "," + objRegion.RegionId;
                }                       
        }
        if (asSize(childs)>0) // STUB удалить if если че
        {
                for (x in childs)
                {
                        var child = childs[x];
                        var s = GetRegionDirectUrlCode(child, true, objRegion.Checked());
                        if (s.length > 0)
                        {
                                retString += "," + s;
                        }
                }
        }
        else
        {
        }

        retString = retString.replace(/^,/g, "");
        var asd2= false;
        if (asd2 == true)
        {
                var asd = false;
                if (retString.length>0)
                {
                        asd = true;
                }
        }
        if (asd2==true)
        {
                if (asd == true)
                {
                }
        }
        return retString;
}

/**
 * Открывает диалог с регионами, при необходимости забирает регионы с сервака
 * @argument sNewRegionsCode {string} Новое значение для __regionsCode, соотв.
 */
function dialogRegionsShow(sNewRegionsCode)
{
        if (RegionsTree.length < 1)
        {
                beginLoadRegions(drawRegions);
        }
        else
        {
                if (sNewRegionsCode != null)
                {
                        drawRegions(sNewRegionsCode);
                }
                else
                {
                        drawRegions(__regionsCode);
                }
        }
}

/**
 * Закрывает диалог с регионами
 * @argument bUpdateCheckedRegions {bool} Сохранять ли изменения чеков регионов, или оставить без изменений
 */
function dialogRegionsClose(bUpdateCheckedRegions)
{
        if (bUpdateCheckedRegions == true)
        {
                UpdateCheckedRegionsList();
                __regionsCode = GetRegionsCode();
                var regionsString = RegionsCode2String(__regionsCode);
                SetRegionsDialogLinkAnchor(regionsString);
        }
        $('#regions_dialog').dialog('close');
}


function dialogRegionsClearSelectedRegions()
{
        $(':checkbox', '#regions_dialog').each(function()
        {
                $(this).attr('checked', false);
        });
}

function RegionsCode2XML()
{
        var ret = "<regions>";
        ret += "<human>" + RegionsCode2String("", false) + "</human>";
        
        ret += "<turing>" + __regionsCode + "</turing>";
        
        ret += "</regions>";
        return ret;
}

function GetBranchHTML(objRegion, level)
{
        var retHTML = "";
 
        if (level == null)
        {
                level = 0;
        }
        for (var i=0;i<=level;i++)
        {
               //retHTML += "--";
        }
       
        var childRegions = objRegion.getChildRegions();
        level++;
        var bContainsChilds = false;
        var childsHTML = "";
        for (x in childRegions)
        {
                var childRegion = childRegions[x];
                childsHTML += GetBranchHTML (childRegion, level);
                bContainsChilds = true;
        }

        if (bContainsChilds == true)
        {
                //alert(objRegion.Name + " -- " + bContainsChilds);
                retHTML +=      '<li class="qqq">' + "\r\n" +
                                        '<div>' + "\r\n" +
                                                
                                                '<i class="expander collapsed"><!-- --></i>' + "\r\n" +
                                                // STUB10 - см. STUB10src
                                                '<input type="checkbox" id="' + objRegion.RegionId + '" />' +
                                                '<label for="' + objRegion.RegionId + '">' +
                                                        objRegion.Name +
                                                '</label>' +
                                        '</div>' + "\r\n" +
                                        '<ul>' + "\r\n" +
                                                childsHTML + "\r\n" +
                                        '</ul>' + "\r\n" +
                                '</li>' + "\r\n";
        }
        else
        {
                retHTML +=      '<li>' + "\r\n" +
                                        '<div>' + "\r\n" +
                                                
                                                '<i class="expander collapsed" style="visibility: hidden;"><!-- --></i>' + "\r\n" +
                                                // STUB10 - см. STUB10src
                                                '<input type="checkbox" id="' + objRegion.RegionId + '" />' +
                                                '<label for="' + objRegion.RegionId + '">' +
                                                        objRegion.Name +
                                                '</label>' + 
                                        '</div>' + "\r\n" +
                                '</li>' + "\r\n";
        }

        return retHTML;
}