/*
 * работа с AJAX
 */

var xmlHttp = createXMLHTTPRequestObject(); //в этой переменной хранится ссылка на объект XMLHTTPRequest
var showDebugError = true;
var suggArray = new Array(); //массив с текстом подсказок
var suggCurrentPos = -1; //текущая позиция подсказки
var suggCount = 0; //количество подсказок
var targetElement; //text input element
var idScroll; //идентификатор вывода списка
var idSuggest; //идентификатор вывода подсказок
var categoriesElement; //ссылка на элемент вывода списка категорий
var selectedCatId; //этот идентификатор необходимо выделить (такая необходимость возникает при возврате в мастере назад)
var selectedAdtypesId;//этот идентификатор необходимо выделить (такая необходимость возникает при возврате в мастере назад)
var txtCityIdArray = new Array(); //массив идентификаторов городов
var domainPageTitleArray = new Array(); //массив заголовков страниц доменов
var metaYandexArray = new Array(); //массив meta-кода для Yandex
var metaGoogleArray = new Array(); //массив meta-кодя для Google


//тоже самое, что прописать это в body html-документа
window.onclick = hideSuggestions;
window.onload = init;

//функция показывает ошибку пользователю в зависимости от уровня показываемых ошибок
//aErroString - текст ошибки
//aShowDebugError - показывать оригинальный текст ошибок
//aGenerateThrow - флаг генерации исключения
function showError(aErrorString, aShowDebugError, aGenerateThrow){
    var errorText;
    if (aShowDebugError){
        errorText = aErrorString;
    }else{
        errorText = "Ой, что-то пошло не так. Попробуйте сделать тоже самое еще раз, должно получиться!";
    }

    if (aGenerateThrow){
        throw(errorText);
    }else{
        alert(errorText);
    }
}

//начальная инициализация
function init(){
    var tCityName = document.getElementById("txtCityName");
    if (tCityName != null){
        //отключаю автодополнение со стороны броузера
        tCityName.setAttribute("autocomplete", "off");
    }
}

//создаю объект XMLHTTPRequest
function createXMLHTTPRequestObject(){
    var xmlHttp;

    xmlHttp = false;
    //если сценарий запущен под управлением IE
    if (window.ActiveXObject){
        try{
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        }catch(e){
            xmlHttp = false;
        }
    }else{ //сценарий запущен под управлением другого броузера
        try{
            xmlHttp = new XMLHttpRequest();
        }catch(e){
            xmlHttp = false;
        }
    }

    if (!xmlHttp){
        showError("Произошла ошибка при создании объекта XMLHttpRequest", showDebugError, true);
    }

    return xmlHttp;
}

//отправляю запрос серверу на получение интересующего списка
function sendSearchString(aSendData, aHandleRequestStateChange){
    if (!xmlHttp) return false; //не удалось инициализировать XMLHttpRequest;

    //если xmlHttp еще занят, то не отправляю новые запросы
    if (!(xmlHttp.readyState == 0 || xmlHttp.readyState == 4)) return false;

    try{
        xmlHttp.open("post", "/ajax/get_response.php", true);
        xmlHttp.onreadystatechange = aHandleRequestStateChange;
        xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xmlHttp.setRequestHeader("Content-length", aSendData.length);
        xmlHttp.setRequestHeader("Connection", "close");
        xmlHttp.send(aSendData);
    }catch(e){
        showError("Не удалось соединиться с сервером: " + e.toString(), showDebugError, false);
        return false;
    }

    return true;
}

//читаю ответ сервера
function handleRequestStateChange(){
    if (xmlHttp.readyState == 4){ //ответ от сервера полностью получен
        if (xmlHttp.status == 200){ //статус ответа HTTP равен "OK"
            try{
                //обрабатываю полученный ответ
                parseServerResponse('city');
            }catch(e){
                if (showDebugError){
                    showError("Ошибка чтения ответа сервера: " + e.toString(), showDebugError, false);
                }
            }
        }
    }
}

//читаю ответ от сервера (вариант для получения категорий)
function handleRequestPartitionsChange(){
    if (xmlHttp.readyState == 4){ //ответ от сервера полностью получен
        if (xmlHttp.status == 200){ //статус ответа HTTP равен "OK"
            try{
                //обрабатываю полученный ответ
                parseServerResponse('catList');
                getAdtypes();
            }catch(e){
                if (showDebugError){
                    showError("Ошибка чтения ответа сервера: " + e.toString(), showDebugError, false);
                }
            }
        }
    }
}

function handleRequestGetAdtypes(){
    if (xmlHttp.readyState == 4){ //ответ от сервера полностью получен
        if (xmlHttp.status == 200){ //статус ответа HTTP равен "OK"
            try{
                //обрабатываю полученный ответ
                parseServerResponse('adtypesList');
            }catch(e){
                if (showDebugError){
                    showError("Ошибка чтения ответа сервера: " + e.toString(), showDebugError, false);
                }
            }
        }
    }
}
//обрабатываю ответ от сервера
//aResponseType - тип ответа от сервера
function parseServerResponse(aResponseType){
    var xmlResponse = xmlHttp.responseXML;
    //alert('recieve!' + xmlHttp.responseText);
    //предотвращаю потенциальные ошибки в IE и Opera
    if (!xmlResponse || !xmlResponse.documentElement){
        showError("Не верная струкрута XML-документа: " + xmlHttp.responseText, showDebugError, false);
    }
    var rootNodeName = xmlResponse.documentElement.nodeName;
    //потенциальная ошибка в FireFox
    if (rootNodeName == "parseerror") showError("Не верная струкрута XML-документа: " + xmlHttp.responseText, showDebugError, false);

    //ссылка на корневой элемент
    var rootNode = xmlResponse.documentElement;
    //массив названий
    var responseTitleArray = rootNode.getElementsByTagName("name");
    //массив ссылок на страницы

    if (aResponseType == 'city'){ //получаю список городов
        var responseUrlArray = rootNode.getElementsByTagName("url");
        var responseMetaYandexArray = rootNode.getElementsByTagName("metaYandex");
        var responseMetaGoogleArray = rootNode.getElementsByTagName("metaGoogle");
        var responseCityId = rootNode.getElementsByTagName("cityId");
        var responseDomainPageTitle = rootNode.getElementsByTagName("pageTitle");
        
        suggCount = responseTitleArray.length; //запомню общее количество подсказок
        if (suggCount != 0){
            //alert(targetElement.value);
            var paramArray = new Array(responseTitleArray, responseUrlArray, responseMetaYandexArray, responseMetaGoogleArray, responseCityId, responseDomainPageTitle);
            showSuggestions(paramArray, idScroll, idSuggest);
        }else{//если подсказок нет, то прячу все
            hideSuggestions(idScroll);
        }
    }else if (aResponseType == 'catList'){ //список категорий
        var responseIDArray = rootNode.getElementsByTagName("id");
        showCategoryList(responseTitleArray, responseIDArray, categoriesElement);
    }else if (aResponseType == 'adtypesList'){
        var responseIDArray = rootNode.getElementsByTagName("id");
        showAdtypesList(responseTitleArray, responseIDArray);
    }
    
//    var titles = "";
//    for (var i = 0; i < responseTitleArray.length; i++){
//        titles += responseTitleArray.item(i).firstChild.data + ", url: " + responseUrlArray.item(i).firstChild.data + "<br>";
//    }

    
    //document.getElementById("cityName").innerHTML = "Ответ: " + titles;
}

//отображаю список категорий
function showCategoryList(aTitleArray, aIDArray, aCategoriesElement){
    if (aCategoriesElement == null) return false; //ссылка на элемент вывода категорий должен быть инициализирован
    if (aTitleArray.length == 0) return false;
    if (aIDArray.length == 0) return false;
    if (aTitleArray.length != aIDArray.length) return false; //массивы должны совпадать по размеру

    var slCategories = "<select class='blackNormalText' name='slCategories' id='slCategories' onchange='getAdtypes();'>"; //список выбора категорий
    //строю список подсказок в формате html
    for (var i = 0; i < aTitleArray.length; i++){
        var catID = aIDArray.item(i).firstChild.data; //идентификатор категории
        var catName = aTitleArray.item(i).firstChild.data; //наименование категории

        var selectedFlag = '';
        if (selectedCatId == catID){
            selectedFlag = ' selected';
        }
        slCategories += "<option class='blackNormalText' value='" + catID + "'" + selectedFlag + ">  &nbsp;&nbsp;&nbsp; &raquo;&raquo; " + catName + "</option>";
    }

    slCategories += "</select>";

    
    aCategoriesElement.innerHTML = slCategories;

    //getAdtypes();
    return true;
}

//отображаю список категорий
function showAdtypesList(aTitleArray, aIDArray){
    if (aTitleArray.length == 0) return false;
    if (aIDArray.length == 0) return false;
    if (aTitleArray.length != aIDArray.length) return false; //массивы должны совпадать по размеру

    var slAdtypes = "<select name='slAdTypes' id='slAdTypes'>"; //список выбора категорий
    //строю список подсказок в формате html
    for (var i = 0; i < aTitleArray.length; i++){
        var adtypeID = aIDArray.item(i).firstChild.data; //идентификатор категории
        var adtypeName = aTitleArray.item(i).firstChild.data; //наименование категории

        var selectedFlag = '';
        if (selectedAdtypesId == adtypeID){
            selectedFlag = ' selected';
        }
        slAdtypes += "<option value='" + adtypeID + "'" + selectedFlag + ">  &nbsp;&nbsp;&nbsp; &raquo;&raquo; " + adtypeName + "</option>";
    }

    slAdtypes += "</select>";


    var adtypesElement = document.getElementById('getAdtypes');
    adtypesElement.innerHTML = slAdtypes;

    return true;
}

//событие, которое возникает при выборе раздела в форме подачи объявления
//aPartitionId - идентификатор выбранного раздела
//aDvCategoriesID - идентификатор div, где будут выводиться категории
//aSelectedCatID - указанный идентификатор категории необходимо будет выделить
function getCategories(aPartitionId, aDvCategoriesID, aSelectedCatID, AselectedTypeID){
    var adtypesElement = document.getElementById('getAdtypes');
    adtypesElement.innerHTML = '<select name="slAdTypes" id="slAdTypes">';
    adtypesElement.innerHTML += '<option value="0"></option>';
    adtypesElement.innerHTML += '</select>';

    if (aPartitionId <= 0){ //выбрано информационное сообщение, а не сам раздел
        return;
    }

    selectedCatId = aSelectedCatID;
    selectedAdtypesId = AselectedTypeID;
    
    categoriesElement = document.getElementById(aDvCategoriesID);
    if (categoriesElement == null){ //элемент с таким идентификатором не найден
        //вывожу ошибку
        showError("Не удалось найти элемент по идентификатору: " + aDvCategoriesID, showDebugError, false);
        return;
    }

    categoriesElement.innerHTML = "Loading. Wait please...";

    sendSearchString(aDvCategoriesID + "=" + aPartitionId, handleRequestPartitionsChange);
    //alert('sent');
}

function getAdtypes(){
    var partElement = document.getElementById('slPartitions');
    var catElement = document.getElementById('slCategories');

    if (partElement == null) return false;
    if (catElement == null) return false;

    if ( (partElement.value > 0) && (catElement.value > 0) ){
        var adtypesElement = document.getElementById('getAdtypes');
        adtypesElement.innerHTML = 'loading, please be patient...';
        
        //alert('p:' + partElement.value + ';c:' + catElement.value);
        sendSearchString("getAdtypes=part" + partElement.value + "cat" + catElement.value, handleRequestGetAdtypes);
    }

    return true;
}

//событие, происходит, когда пользователь что-то вводит в input
//ev - событие
function changeInput(evnt){
    //получаю ссылку на событие
    evnt = (!evnt) ? window.event : evnt;
    //проверю, что получено именно то событие, которое необходимо
    if (evnt.type != "keyup") return;
    //получаю ссылку на приемник события
    var eTarget = (!evnt.target) ? evnt.srcElement : evnt.target;
    if (eTarget.nodeType == 3) eTarget = eTarget.parentNode;
    //id того input, который отправляет сообщения
    var idTarget = eTarget.id; //text input id
    var valueTarget = eTarget.value;
    targetElement = eTarget;
    idScroll = idTarget + 'Scroll'; //идентификатор вывода списка
    idSuggest = idTarget + 'Suggest'; //идентификатор вывода подсказок
    //получаю код нажатой клавиши
    var keyCode = (evnt.charCode) ? evnt.charCode : ((evnt.keyCode) ? evnt.keyCode : (evnt.which) ? evnt.which : 0);

    toggleCityListVisible(true);
    if (keyCode == 13){ //нажата клавиша Enter
        if (suggCurrentPos >= 0){ //подсказка выделена
            //меняю значение текстового поля
            document.getElementById(eTarget.id).value = suggArray[suggCurrentPos];

            //устанавливаю в meta-коды в соответствующий поля
            setMetaParams(suggCurrentPos);
            
            //прячу подсказки
            hideSuggestions(idScroll);

            toggleCityListVisible(false);
            
            return;

//            location.href = document.getElementById("a" + suggCurrentPos).href; //извлекаю ссылку страницы, на которую ведет подсказка
            //вставляю текст города в текствогое поле
            
            //valueTarget = document.getElementById("a" + suggCurrentPos).value;
        }
    }if (keyCode == 27){ //нажата клавиша Esc
        //прячу подсказки
        hideSuggestions(idScroll);

        return;
    }else if (keyCode == 40){ //нажата клавиша вниз
        if (suggCurrentPos == -1){//ни одна подсказка еще не выделена
            suggCurrentPos = 0; //выбираю самую верхнюю подсказку
            var suggCurrent = document.getElementById("tr" + (suggCurrentPos)); //ссылка на текущую подсказку
            suggCurrent.className = "hightlightrow";
        }else{
            var suggCurrent = document.getElementById("tr" + suggCurrentPos); //ссылка на текущую подсказку
            suggCurrent.className = "";
            if (suggCurrentPos == suggCount - 1){ //текущей является последняя подсказка в списке
                suggCurrentPos = 0;
            }else{
                suggCurrentPos ++;
            }
            suggCurrent = document.getElementById("tr" + (suggCurrentPos)); //ссылка на новую подсказку
            suggCurrent.className = "hightlightrow";
        }

        //меняю значение текстового поля
        document.getElementById(eTarget.id).value = suggArray[suggCurrentPos];

        return; //выхожу из функции
    }else if (keyCode == 38){ //нажата клавиша вверх
        if (suggCurrentPos < 0){//ни одна подсказка еще не выделена
            suggCurrentPos = suggCount - 1; //выбираю последнюю подсказку
            var suggCurrent = document.getElementById("tr" + (suggCurrentPos));
            suggCurrent.className = "hightlightrow";
        }else{
            var suggCurrent = document.getElementById("tr" + suggCurrentPos); //ссылка на текущую подсказку
            suggCurrent.className = "";

            if (suggCurrentPos == 0){ //выделена самая верхняя подсказка
                suggCurrentPos = suggCount - 1; //выбираю последнюю подсказку
            }else{
                suggCurrentPos --;
            }
            suggCurrent = document.getElementById("tr" + (suggCurrentPos)); //ссылка на новую подсказку
            suggCurrent.className = "hightlightrow";
        }
        //меняю значение текстового поля
        document.getElementById(eTarget.id).value = suggArray[suggCurrentPos];

        return; //выхожу из функции
    }else if (keyCode == 37){ //нажата клавиша влево
        //делать ни чего не надо
        return;
    }else if (keyCode == 39){ //нажата клавиша вправо
        //делать ни чего не надо
        return;
    }

    //document.getElementById("cityName").innerHTML = "Ответ: " + valueTarget;

    //начинаю отправлять запросы серверу только тогда, когда строка будет больше определенного числа символов
    if (valueTarget.length > 2){
        sendSearchString(idTarget + "=" + encodeURIComponent(valueTarget), handleRequestStateChange);
        //document.getElementById("cityName").innerHTML = "Отправлено: " + idTarget + "=" + encodeURIComponent(valueTarget);
    }else{
        hideSuggestions(idScroll);
    }
}

function toggleCityListVisible(Ashow){
    hideRow = document.getElementById('cityListHidden');
    if (hideRow != null){
        if (!Ashow){
            hideRow.style.display = 'none';
            targetElement.className = 'city-good';
        }else{
            hideRow.style.display = 'block';
            targetElement.className = '';
        }
    }
}

//обработка события при нажатии на подсказку
function suggestionsOnClick(Aid, Aname, Aurl){
    //alert('id: ' + Aid + ', url: ' + Aurl + ', name: ' + Aname);
    document.getElementById('txtCityName').value = Aname;

    toggleCityListVisible(false);
    return false; //"location.href=\"" + Aurl + "\"";
}

//отображаю подсказки пользователю
//aParamArray - массив параметров, содержащий массивы полученых данных от севера
//aIDScroll - идентификатор списка, куда выводить
//aIDSuggest - идентификатор подсказок, куда выводить
function showSuggestions(aParamArray, aIDScroll, aIDSuggest){
    if (aParamArray.length == 0) return false;
    //aSuggestionsArray - массив подсказок
    var aSuggestionsArray = aParamArray[0];
    //aUrlArray - массив url ссылок дя каждой подсказки
    var aUrlArray = aParamArray[1];
    if (aSuggestionsArray.length == 0) return false;
    if (aUrlArray.length == 0) return false;
    if (aSuggestionsArray.length != aUrlArray.length) return false; //массивы должны совпадать по размеру

    suggCurrentPos = -1; //сбрасываю индекс текущей подсказки

    var tblSuggestions = "<table style='width: " + targetElement.style.width + "'>"; //таблица подсказок
    //строю список подсказок в формате html
    for (var i = 0; i < aSuggestionsArray.length; i++){
        var suggUrl = aUrlArray.item(i).firstChild.data; //url текущей подсказки
        var suggText = aSuggestionsArray.item(i).firstChild.data; //текст текущей подсказки
        if (aParamArray.length >= 4){
            try{
                metaYandexArray[i] = aParamArray[2].item(i).firstChild.data;
            }catch(e){
                metaYandexArray[i] = '';
            }
            try{
                metaGoogleArray[i] = aParamArray[3].item(i).firstChild.data;
            }catch(e){
                metaGoogleArray[i] = '';
            }

            try{
                txtCityIdArray[i] = aParamArray[4].item(i).firstChild.data;
            }catch(e){
                txtCityIdArray[i] = '';
            }

            try{
                domainPageTitleArray[i] = aParamArray[5].item(i).firstChild.data;
            }catch(e){
                domainPageTitleArray[i] = '';
            }
        }

        suggArray[i] = suggText;
        tblSuggestions += "<tr id='tr" + i + "' onclick='suggestionsOnClick(" + i + ", \"" + suggText + "\", \"" + suggUrl + "\");' onmouseover='suggOnMouseOver(this);' onmouseout='suggOnMouseOut(this);'>" +
            "<td align='left'><a id='a" + i + "' href='" + suggUrl + "'>" + suggText + "</a></td></tr>";
    }
    tblSuggestions += "</table>";

    var dScroll = document.getElementById(aIDScroll);
    var dSuggest = document.getElementById(aIDSuggest);
    dScroll.style.width = targetElement.style.width;
    dSuggest.style.width = targetElement.style.width;
    //прокручиваю в начало списка
    dScroll.scrollTop = 0;
    //обновляю список подсказок
    dSuggest.innerHTML = tblSuggestions;
    dScroll.style.visibility = "visible";

    return true;
}

//указатель мыши находится на строке кодсказки
function suggOnMouseOver(aSuggest){
    aSuggest.className = "hightlightrow";
}

//указатель мыши покинул строку подсказки
function suggOnMouseOut(aSuggest){
    aSuggest.className = "";
}

//прячу подсказки
//aIDScroll - идентификатор списка, который необходимо спрятать
function hideSuggestions(aIDScroll){
    var dScroll = document.getElementById(aIDScroll);
    if (dScroll != null){
        dScroll.style.visibility = "hidden";
    }else{//не удалось найти подсказку по идентификатору. В этом случае прячу те, которые знаю
        dScroll = document.getElementById('txtCityNameScroll');
        if (dScroll != null){
            dScroll.style.visibility = "hidden";
        }
    } 
    

    suggCurrentPos = -1;
}

//устанавливаю в соответствующие поля meta-код
function setMetaParams(aSuggCurrentPos){
    if (aSuggCurrentPos < 0){
        return;
    }
    var txtCityId = document.getElementById('txtCityId');
    if (txtCityId != null){
        txtCityId.value = txtCityIdArray[aSuggCurrentPos];
    }

    var txtDomainPageTitle = document.getElementById('txtDomainPageTitle');
    if (txtDomainPageTitle != null){
        txtDomainPageTitle.value = domainPageTitleArray[aSuggCurrentPos];
    }
    var txtMetaYandex = document.getElementById('txtYandexVerify');
    if (txtMetaYandex != null){
        txtMetaYandex.value = metaYandexArray[aSuggCurrentPos];
    }
    var txtMetaGoogle = document.getElementById('txtGoogleVerify');
    if (txtMetaGoogle != null){
        txtMetaGoogle.value = metaGoogleArray[aSuggCurrentPos];
    }
}

//проверяю поля, которые должны быть заполнены
function checkFields(){
    
}
