﻿// --------------------------------------------------------------------------------------
// Конструктор поисковой формы
// pSFParams - параметры поисковой формы
// --------------------------------------------------------------------------------------
function SearchForm(pObj)
{
    
    
                     
    // Получаем страницы формы
    pObj.Pages = new Array(pObj.PageIDs.length);
    for (var i=0; i<pObj.PageIDs.length; i++)
        pObj.Pages[i] = document.getElementById(pObj.PageIDs[i]);
    
    // Получаем ссылки
    pObj.LeftLink = document.getElementById(pObj.LeftLinkID);
    pObj.LeftLink.pSF = pObj;
    pObj.LeftLink.onclick = SearchForm_LeftLinkClick;
    pObj.RightLink = document.getElementById(pObj.RightLinkID);
    pObj.RightLink.pSF = pObj;
    pObj.RightLink.onclick = SearchForm_RightLinkClick;
    
    // Методы
    pObj.SetViewMode = SearchForm_SetViewMode;
    pObj.AddButton = SearchForm_AddButton;
    
    // Инициализируем ссылки выделить / очистить для типов объектов
    pObj.pObjTypesContainer = document.getElementById('object_types');
    if (pObj.pObjTypesContainer)
    {
        // Получаем все галочки
        pObj.pObjTypeItems = pObj.pObjTypesContainer.getElementsByTagName('INPUT');

        // Создаем контейнер (center)
        var pCenter = document.createElement('CENTER');
        pObj.pObjTypesContainer.appendChild(pCenter);
        
        // Создаем ссылку "Выделить все"
        pObj.pOTSelectAll = pObj.AddButton(pCenter, 'Выделить все', SearchForm_SelectAllClick);
        
        // Создаем промежуток
        var pText = document.createTextNode(' / ');
        pCenter.appendChild(pText);
        
        // Создаем ссылку "Снять выделение со всех"
        pObj.pOTSelectClear = pObj.AddButton(pCenter, 'Снять выделение со всех', SearchForm_SelectClearClick);
    }
    
    return pObj;
}

// --------------------------------------------------------------------------------------
// Создать кнопку
function SearchForm_AddButton(pParent, sInnerHTML, pfEventHandler)
{
    var pNew = document.createElement('A');
    pNew.pSF = this; pNew.href = '#';
    if (sInnerHTML) pNew.innerHTML = sInnerHTML;
    if (pfEventHandler) pNew.onclick = pfEventHandler;
    if (pParent) pParent.appendChild(pNew);
    return pNew;
}

// --------------------------------------------------------------------------------------
// Установить режим отображения
function SearchForm_SetViewMode(iNewViewMode)
{
    this.ViewMode = iNewViewMode;
    
    // Вспомогательные переменные
    var iL = this.ViewMode == 1 ? 0 : (this.ViewMode - 1 == 1 ? 3 : 1);
    var iR = this.ViewMode  == this.MaxViewMode ? 3 : (this.ViewMode  + 1 == this.MaxViewMode ? 0 : 2);
    
    // Тексты и стили ссылок
    var pTexts = ['Сложная форма', 'Сузить форму', 'Расширить форму', 'Сокращенная форма'];
    var pStyles = ['Larger', 'Smaller', 'Larger', 'Smaller'];
    
    // Правим текст и изображения на картинках
    this.LeftLink.childNodes[0].data = pTexts[iL];
    this.LeftLink.className = 'vm_link left L' + pStyles[iL];
    this.RightLink.childNodes[0].data = pTexts[iR];
    this.RightLink.className = 'vm_link right R' + pStyles[iR];
    
    // Показываем/скрываем панели формы
    for (var i=0; i<this.MaxViewMode; i++)
        this.Pages[i].style.display = i + 1 <= this.ViewMode ? 'block' : 'none';
}

// --------------------------------------------------------------------------------------
// Щелчек по левой ссылке
function SearchForm_LeftLinkClick()
{
    var pSF = this.pSF;
    pSF.SetViewMode(pSF.ViewMode == 1 ? pSF.MaxViewMode : pSF.ViewMode - 1);
    this.blur();
    return false;
}

// --------------------------------------------------------------------------------------
// Щелчек по правой ссылке
function SearchForm_RightLinkClick()
{
    var pSF = this.pSF;
    pSF.SetViewMode(pSF.ViewMode == pSF.MaxViewMode ? 1 : pSF.ViewMode + 1);
    this.blur();
    return false;
}

// --------------------------------------------------------------------------------------
// Щелчек по кнопке "Выделить все (типы объектов)" 
function SearchForm_SelectAllClick()
{
    var pSF = this.pSF;
    for (var i=0; i<pSF.pObjTypeItems.length; i++)
        pSF.pObjTypeItems[i].checked = true;
    return false;
}

// --------------------------------------------------------------------------------------
// Щелчек по кнопке "Снять выделение со всех (типов объектов)" 
function SearchForm_SelectClearClick()
{
    var pSF = this.pSF;
    for (var i=0; i<pSF.pObjTypeItems.length; i++)
        pSF.pObjTypeItems[i].checked = false;
    return false;        
}


// --------------------------------------------------------------------------------------
// Конструктор таблицы результатов
// sRTParams - таблицы результатов
// --------------------------------------------------------------------------------------
function ResultTable(pObj)
{
    
    
    // Задаем свойства: таблица и дорожки
    pObj.pTable = document.getElementById(pObj.ID);
    pObj.pRows = pObj.pTable.getElementsByTagName('TR');


    // Обновляем строку формата ссылки и получаем кол-во аргументов
    pObj.iLinkAttrCount = 0;
    var iStart = 0, iEnd = 0, s = pObj.ObjInfoLinkFmt;
    do
    {
        iStart = s.indexOf('{', iStart); if (iStart == -1) continue;
        iEnd = s.indexOf('}', iStart); if (iEnd == -1) continue;
        pObj.ObjInfoLinkFmt = pObj.ObjInfoLinkFmt.replace(s.substr(iStart + 1, iEnd - iStart - 1), pObj.iLinkAttrCount)
        iStart = (iEnd + 1 < pObj.ObjInfoLinkFmt.length) ? iEnd + 1 : -1;
        pObj.iLinkAttrCount++;
    }
    while (iStart >= 0 && iEnd >= 0);

    // Для всех дорожек (опуская заглавную)
    for (var i = 1; i < pObj.pRows.length; i++)
    {
        // Получаем ссылку для каждой дорожки
        pObj.pRows[i].href = pObj.ObjInfoLinkFmt;
        for (var k = 0; k < pObj.iLinkAttrCount; k++)
            pObj.pRows[i].href = pObj.pRows[i].href.replace('{' + k + '}', pObj.ObjInfoParams[(i - 1) * pObj.iLinkAttrCount + k]);

        // Создаем обработчик на щелчек
        pObj.pRows[i].onclick =  function() { location.href = this.href; return false; } ;
            
        // Создаем обработчики мыши
        var bAlt = i % 2 ? true : false;
        var bPR = pObj.ObjInfoParams[(i - 1) * pObj.iLinkAttrCount + 1] == '1' ? true : false;
        pObj.pRows[i].sBaseClass = (bAlt ? 'alt ' : ' ') + (bPR ? 'private ' : ' ');
        pObj.pRows[i].onmouseover = function() { this.className = this.sBaseClass + 'cur'; };
        pObj.pRows[i].onmouseout = function() { this.className = this.sBaseClass };
    }
}


// --------------------------------------------------------------------
// Контструктор MultiSelect'а
// sParams - параметры
// --------------------------------------------------------------------
function MultiSelect(pObj)
{
    var i, k;
  

    // --------------------------------------------------------------------
    // Определяем методы
    pObj.GetHiddenField = MultiSelect_GetHiddenField;
    pObj.SetHiddenField = MultiSelect_SetHiddenField;
    pObj.UpdateVisibleList = MultiSelect_UpdateVisibleList;

    // --------------------------------------------------------------------
    // Получаем необходимые контролы
    pObj.pContainer = document.getElementById(pObj.sContainerID);
    pObj.pDDL = document.getElementById(pObj.sDDLID);
    pObj.pHF = document.getElementById(pObj.sHiddenID);
    pObj.PopupWindow = MultiSelect_PopupWindow();    // попап
    
    // --------------------------------------------------------------------
    // Получаем все элементы в массив
    pObj.pItems = new Array();
    for (i = 0; i < pObj.pDDL.options.length; i++)
        if (!isNaN(pObj.pDDL.options[i].value) && pObj.pDDL.options[i].value != 0)
            pObj.pItems.push(MultiSelectListItem(Number(pObj.pDDL.options[i].value), pObj.pDDL.options[i].text, false));

    // --------------------------------------------------------------------
    
    // Создаем кнопку Редактировать
    pObj.BtnEditList = Util_CreateButton(pObj, null, pObj.pContainer, 'button', 'Выбрать');
    pObj.BtnEditList.onclick = function () { this.Creator.PopupWindow.Popup(this.Creator); this.blur(); return false; }
    
    // Создаем кнопку Очистить
    pObj.BtnClearList = Util_CreateButton(pObj, null, pObj.pContainer, 'button', 'Очистить');
    pObj.BtnClearList.onclick = function () 
    { 
        for (var i=0; i<this.Creator.pItems.length; i++) this.Creator.pItems[i].selected = false; 
        this.Creator.UpdateVisibleList(); this.Creator.SetHiddenField(); return false;
    }
    
    // Завершаем обтекание
    var pDiv = Util_CreateElement(null, 'DIV', null, null, pObj.pContainer).style.clear = 'both';
   
    // Создаем список отображаемых элементов
    pObj.pSelectedList = Util_CreateElement(null, 'DIV', null, null, pObj.pContainer, 'list');
    pObj.pSelectedList.style.height = (pObj.iListSize * 16 + 2) + 'px';
    
    // Создаем галочку Исключить
    if (pObj.bExcludeVisible)
    {
        // Создаем контейнер
        pObj.pCbContainer = Util_CreateElement(null, 'DIV', null, null, pObj.pContainer, 'checkbox');
        
        // Создаем галочку
        pObj.pCbExclude = Util_CreateElement(pObj, 'INPUT', 'checkbox', pObj.pContainer.id + 'CbExclude', pObj.pCbContainer);
        pObj.pCbExclude.onclick = function () { this.Creator.SetHiddenField(); }

        // И подпись к ней
        if (pObj.sExcludeText)
        {
            var pLabel = Util_CreateElement(null, 'LABEL', null, null, pObj.pCbContainer);
            pLabel.innerHTML = pObj.sExcludeText;
            pLabel.htmlFor = pObj.pCbExclude.id;
        }
    }
    // Работаем с данными
    pObj.GetHiddenField();
    pObj.UpdateVisibleList();
    pObj.pDDL.parentNode.style.display = 'none';
}

// --------------------------------------------------------------------
// Получить выделение из скрытого поля        
function MultiSelect_GetHiddenField()
{
    var sValue = this.pHF.value ? this.pHF.value : '';
    
    // Исключать значения?
    if (sValue.indexOf('!') != -1)
    {
        sValue = sValue.substr(1, sValue.length - 1);
        this.pCbExclude.checked = true;
    }
    else
        this.pCbExclude.checked = false;
    
    // Получаем установленные галочки
    var pSelection = sValue.split('|');
    for (var i = 0; i < this.pItems.length; i++)
        for (var k = 0; k < pSelection.length; k++)
            if (this.pItems[i].id == pSelection[k])
                this.pItems[i].selected = true;
}

// --------------------------------------------------------------------
// Установить выделение в скрытое поле        
function MultiSelect_SetHiddenField()
{
    this.pHF.value = '';
    
    for (var i = 0; i < this.pItems.length; i++)
        if (this.pItems[i].selected)
            this.pHF.value += (this.pHF.value == '' ? '' : '|') + this.pItems[i].id;
    
    if (!this.pHF.value) { this.pHF.value = '*'; return; }
    if (this.pCbExclude.checked) this.pHF.value = '!' + this.pHF.value;
}

// --------------------------------------------------------------------
// Обновить список на форме
function MultiSelect_UpdateVisibleList()
{
    this.pSelectedList.innerHTML = '';
    this.pItems.sort(MultiSelectListItem_Sort)
    for (var i = 0; i < this.pItems.length; i++)
    {
        if (this.pItems[i].selected)
        {
            var pA = Util_CreateButton(this, null, null, null, this.pItems[i].name, MultiSelect_RemoveOneRec);
            pA.title = 'Кликните для удаления записи \'' + this.pItems[i].name + '\' из списка';
            pA.iID = this.pItems[i].id;
            this.pSelectedList.appendChild(pA);
        }
    }      
}

// --------------------------------------------------------------------
// Удалить одну запись из списка
function MultiSelect_RemoveOneRec()
{
    pMS = this.Creator;
    for (var i = 0; i < pMS.pItems.length; i++) 
        if (pMS.pItems[i].id == this.iID) { pMS.pItems[i].selected = false; break; }
    this.Creator.pSelectedList.removeChild(this);
    pMS.SetHiddenField();
    return false;
}

// --------------------------------------------------------------------
// Конструктор элемента списка для MultiSelect'a
// --------------------------------------------------------------------
function MultiSelectListItem(iID, sName, bSelected)
{
    var pItem = new Object();
    pItem.id = iID;
    pItem.name = sName;
    pItem.selected = bSelected;
    return pItem;
}

// --------------------------------------------------------------------
// Функция сортировки для итемов списка
function MultiSelectListItem_Sort(pItem1, pItem2)
{
    if (pItem1.selected && !pItem2.selected) return -1;
    if (!pItem1.selected && pItem2.selected) return 1;
    if (pItem1.name < pItem2.name) return -1;
    if (pItem1.name > pItem2.name) return 1;
    return 0;
}

// --------------------------------------------------------------------
// Конструктор всплывающего окна MultiSelect'a
// --------------------------------------------------------------------
function MultiSelect_PopupWindow()
{
    // Если уже создано возвращаем его
    var pWnd = document.getElementById('ms_popup_container');
    if (pWnd != null) return pWnd;
    
    // Создаем окно-контейнер
    var pWnd = Util_CreateElement(null, 'DIV', null, 'ms_popup_container', Util_GetBody());
    pWnd.pMS = null;
    pWnd.Popup = MultiSelect_PopupWindow_Popup;
    pWnd.ShowMe = MultiSelect_PopupWindow_ShowMe;
    
    // Уведение мыши
    pWnd.onmouseout = function (e) 
    { 
        if (this.style.display == 'none') return;
        var pTarget = window.event == null ? (e.toElement || e.relatedTarget) : window.event.toElement;
        if (!Util_IsParent(pTarget, this)) this.pHideTM = 
            setTimeout("var p = document.getElementById('ms_popup_container'); p.pBtnOk.onclick(); p.style.display = 'none'; clearTimeout(p.pHideTM)", 1000);
    }
    
    // Наведение мыши
    pWnd.onmouseover = function (e) { if (this.pHideTM) {clearTimeout(this.pHideTM); this.pHideTM = null;} };
    
    // Создаем тень
    Util_CreateElement(null, 'DIV', null, 'ms_popup_shadow', pWnd);
    
    // Для сраного IE создаем фрейм
    var IE='\v'=='v';
    if (IE) { pWnd.innerHTML += '<IFRAME frameBorder="0" scrolling="no" id="ms_popup_frame" />'; }
    
    // Создаем контейнер контента
    var pContentContainer = Util_CreateElement(null, 'DIV', null, 'ms_popup_content_container', pWnd);
    pWnd.Content = Util_CreateElement(null, 'DIV', null, 'ms_popup_content', pContentContainer);

    // Создаем заголовок
    pWnd.pHeader = Util_CreateElement(null, 'DIV', null, null, pWnd.Content, 'header');
    pWnd.pHeader.innerHTML = '';
    
    // Создаем кнопку закрыть
    pWnd.pCloseBtn = Util_CreateButton(pWnd, null, pWnd.Content, 'button close', 'X');
    pWnd.pCloseBtn.onclick = function () { p = this.Creator; clearTimeout(p.pHideTM); p.style.display = 'none'; return false; }
    
    // Завершаем обтекание
    Util_CreateElement(null, 'DIV', null, null, pWnd.Content).style.clear = 'both';
    
    // Создаем контейнер для списка + линии
    Util_CreateElement(null, 'DIV', null, null, pWnd.Content, 'line');
    pWnd.pSelectedList = Util_CreateElement(null, 'DIV', null, null, pWnd.Content, 'list');
    Util_CreateElement(null, 'DIV', null, null, pWnd.Content, 'line');
    
    // Создаем кнопку Выделить все
    pWnd.pBtnSelectAll = Util_CreateButton(pWnd, null, pWnd.Content, 'button', 'Выделить все');
    pWnd.pBtnSelectAll.onclick = function ()
    {
        var pCBs = this.Creator.pSelectedList.getElementsByTagName('INPUT');
        for (var i = 0; i < pCBs.length; i++) pCBs[i].checked = true;
        return false;
    };
    
    // Создаем кнопку Очистить
    pWnd.pBtnClear = Util_CreateButton(pWnd, null, pWnd.Content, 'button', 'Очистить');
    pWnd.pBtnClear.onclick = function ()
    {
        var pCBs = this.Creator.pSelectedList.getElementsByTagName('INPUT');
        for (var i = 0; i < pCBs.length; i++) pCBs[i].checked = false;
        return false;
    };
    
    // Создаем кнопку Ок
    pWnd.pBtnOk = Util_CreateButton(pWnd, null, pWnd.Content, 'button ok', 'Ok!');
    pWnd.pBtnOk.onclick = function ()
    {
        var pMS = this.Creator.pMS;
        var pCBs = this.Creator.pSelectedList.getElementsByTagName('INPUT');
        for (var i = 0; i < pMS.pItems.length; i++) pMS.pItems[i].selected = pCBs[i].checked;

        this.Creator.ShowMe(false);    
        pMS.SetHiddenField();
        pMS.UpdateVisibleList();
        return false;
    };
    
    return pWnd;
}

// --------------------------------------------------------------------
// Показать попап для заданного MultiSelect'a
function MultiSelect_PopupWindow_Popup(pMS)
{
    this.pSelectedList.innerHTML = '';
   
    // Сортируем список итемов
    pMS.pItems.sort(MultiSelectListItem_Sort);

    // Идем по всем итемам и добавляем чекбоксы
    for (var i = 0; i < pMS.pItems.length; i++)
    {
        // Создаем контейнер
        var pCBC = Util_CreateElement(null, 'DIV', null, null, this.pSelectedList, 'checkbox');
        
        // Создаем чекбокс
        var pCB = Util_CreateElement(null, 'INPUT', 'checkbox', pMS.pContainer.id + i, pCBC);
        pCB.value = pMS.pItems[i].id;
        if (pMS.pItems[i].selected) pCB.checked = 'checked';
        
        // Создаем подпись
        var pLabel = Util_CreateElement(null, 'LABEL', null, null, pCBC);
        pLabel.innerHTML = pMS.pItems[i].name;
        pLabel.htmlFor = pCB.id;
        
        // Завершаем обтекание
        Util_CreateElement(null, 'DIV', null, null, this.pSelectedList).style.clear = 'both';
    }
    
    // Показываем окно
    this.pHeader.innerHTML = pMS.sCaption;
    this.ShowMe(true, pMS);
    this.pSelectedList.scrollTop = 0;
    this.pMS = pMS;
}

// --------------------------------------------------------------------
// Показать всплывающее окно
function MultiSelect_PopupWindow_ShowMe(bShow, pMS)
{
    if (bShow)
    {
        var pPos = Util_GetAbsolutePosition(pMS.pContainer, Util_GetBody());
        this.style.left = pPos.x + 'px';
        this.style.top = pPos.y + 'px';
        this.style.display = 'block';
    }
    else
        this.style.display = 'none';
    
    return false;
}


// --------------------------------------------------------------------
// Утилитные функции
// --------------------------------------------------------------------

// --------------------------------------------------------------------
// Создать элемент с заданным тегом, айдишником, родителем, классом CSS...
function Util_CreateElement(pCreator, sTag, sType, sID, pParent, sCSSClass)
{
    var pNew = document.createElement(sTag);
    if (pCreator) pNew.Creator = pCreator;
    if (sType) pNew.type = sType;
    if (sID) pNew.id = sID;
    if (sCSSClass) pNew.className = sCSSClass;
    if (pParent) pParent.appendChild(pNew);
    return pNew;
}

// --------------------------------------------------------------------
// Создать кнопку-ссылку
function Util_CreateButton(pCreator, sID, pParent, sCSSClass, sInnerHTML, pfEventHandler)
{
    var pNew = Util_CreateElement(pCreator, 'A', null, sID, pParent, sCSSClass);
    pNew.href = '#';
    if (sInnerHTML) pNew.innerHTML = sInnerHTML;
    if (pfEventHandler) pNew.onclick = pfEventHandler;
    return pNew;
}

// --------------------------------------------------------------------
// Получение абсолютных координат одного объекта относительно другого
function Util_GetAbsolutePosition(pObj, pRelativeTo)
{
	var x = 0; var y = 0;
    while (pObj && pObj != pRelativeTo)
    {
        x += pObj.offsetLeft;
        y += pObj.offsetTop;
        pObj = pObj.offsetParent;
    }
    return {"x": x, "y": y};
}

// --------------------------------------------------------------------
// Добавить обработчик событий
function Util_AddHandler(pNode, sEvent, pFunction) 
{
    if (pNode.addEventListener) 
        pNode.addEventListener(sEvent, pFunction, false); 
    else 
        pNode.attachEvent('on' + sEvent, pFunction);
};

// --------------------------------------------------------------------
// Определить, является ли pParent родителем pChild
function Util_IsParent(pChild, pParent) 
{
    if (!pChild || !pParent) return false;

    while (true) 
    {
        if (pChild == pParent) return true;
        if (pChild.parentElement) 
            pChild = pChild.parentElement;
        else 
        {
            if (pChild.parentNode) pChild = pChild.parentNode; else return false;
        }
    }
}

// --------------------------------------------------------------------
// Получить тег Body
function Util_GetBody()
{
    return document.getElementsByTagName('BODY')[0];
}
