﻿// Библиотека для работы с вебсервисами asp.net
// Автор: Лавриненко Е.А.
// Дата создания: 17.08.2010
// Версия: 1.0.0.3

Rtecho.WS = {}

Rtecho.WS._construct = function () {
    ///.ctor
    /// serviceUrl - url запрашиваемого вебсервиса
    function RequestController(serviceUrl) {
        var ServiceUrl = serviceUrl;
        // функция получения объекта XMLHttpRequest 
        function GetHTTPRequestObject() {
            var xmlhttp = false;
            try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
            catch (e) {
                try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
                catch (E)
                { xmlhttp = false; }
            }

            if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
                xmlhttp = new XMLHttpRequest();
            return xmlhttp;
        }

        /// функция запроса к сервису
        /// xmlhttp - объект   
        /// serviceUrl - url вебсервиса 
        /// remote_func_name - название удалённой процедуры
        /// nvparams - список параметров
        /// onready_func - функция вызываемая на получение результата
        function GetService(xmlhttp, remote_func_name, nvparams, onready_func) {

            //set priveleges
            try {
                netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
            }
            catch (e) { }

            var serviceNamespace = "http://tempuri.org"
            var envelope = "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
        " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
        " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
        " <soap:Body>\n" +
        " <" + remote_func_name + " xmlns=\"http://tempuri.org/\"> \n";
            for (var i = 0; i < nvparams.Length(); i++) {
                envelope += " <" + nvparams[i].name + ">" + nvparams[i].value + "</" + nvparams[i].name + "> \n";
            }

            envelope += " </" + remote_func_name + "> \n" +
        " </soap:Body> \n" +
        "</soap:Envelope>";

            var serviceAction = serviceNamespace + "/" + remote_func_name;
            xmlhttp.open("POST", ServiceUrl, true);
            xmlhttp.onreadystatechange = onready_func;
            xmlhttp.setRequestHeader("Content-Type", "text/xml");
            xmlhttp.setRequestHeader("SOAPAction", serviceAction);
            alert(envelope);
            xmlhttp.send(envelope);
        }

        /// функция обработки результата XMLHttp запроса 
        /// xmlhttp - объект 
        /// remoteFuncName - название вызываемой функции вебсервиса
        /// o_type - тип возвращаемого результата ("list" или "item")
        /// p_func - функция обработки результата - прокидывается до ParceList или ParceItem 
        function ProcessFunc(xmlhttp, remoteFuncName, o_type, o_item, p_func) {

            if (xmlhttp.readyState == 4) {
                if (xmlhttp.status == 200) {
                    var doc = xmlhttp.responseXML;
                    switch (o_type) {
                        case "nvcollection":
                            ParseNVCollection(doc, o_item, p_func);
                            break;
                        case "list":
                            ParseList(doc, o_item, p_func);
                            break;
                        case "item":
                            ParseItem(doc, o_item, p_func);
                            break;
                        default:
                            ParseString(doc, p_func);
                            break;
                    }
                }
            }

            if (xmlhttp.readyState == 1) { }
            if (xmlhttp.readyState == 2) { }
            if (xmlhttp.readyState == 3) { }
            if (xmlhttp.readyState == 4) { }
        }
        /// функция парсинга списка 
        /// doc - xml документ
        /// o_item - тип(название) объекта напр CityInfo
        /// p_func - делегат - ф-ция обработки результата 
        function ParseNVCollection(doc, o_item, p_func) {
            var nodes = doc.getElementsByTagName(o_item);
            var list = new Rtecho.NVCollection;
            for (var i = 0; i < nodes.length; i++) {
                var node = nodes[i];
                var fields = new Rtecho.NVCollection;
                var docelt = node.firstChild;
                if (docelt == null) return list;

                fields.Add(docelt.nodeName, docelt.firstChild.nodeValue);
                while (docelt != null) {
                    // парсится только первый уровень!
                    if (docelt.nodeType == 1 /*Node.ELEMENT_NODE*/) {
                        docelt = docelt.nextSibling;
                        if (docelt != null) {
                            fields.Add(docelt.nodeName, docelt.firstChild.nodeValue);
                        }
                    }
                }
                list.Add(node.nodeName, fields);
            }
            p_func(list);
        }

        function ParseList(doc, type, p_func) {
            alert(doc);
            var nodes = doc.getElementsByTagName(type);
            var list = new Object;

            for (var i = 0; i < nodes.length; i++) {
                var node = nodes[i];
                var item = new Object();
                var docelt = node.firstChild;
                if (docelt == null) return list;
                eval("item." + docelt.nodeName + "='" + docelt.firstChild.nodeValue + "'");
                while (docelt != null) {
                    // парсится только первый уровень!
                    if (docelt.nodeType == 1) {
                        docelt = docelt.nextSibling;
                        if (docelt != null) {
                            eval("item." + docelt.nodeName + "='" + docelt.firstChild.nodeValue + "'");
                        }
                    }
                }
                list[i] = item;
            }
            p_func(list);
        }

        /// получает динамический список
        /// serviceUrl - url сервиса
        /// remoteFuncName - имя удалённой процедуры
        /// params - параметры для передачи в удалённую процедуру (NVCollection)
        /// type - тип списка (напр. CityInfo)
        /// processFunc - функция процессинга списка
        this.GetList = function (remoteFuncName, params, type, processFunc) {
            var xmlHttp = GetHTTPRequestObject();
            if (params == null) params = new Rtecho.NV.Collection;

            var res = function () { ProcessFunc(xmlHttp, remoteFuncName, "list", type, processFunc); }
            GetService(xmlHttp, remoteFuncName, params, res);
        }
    }
    this.RequestController = RequestController;
}
Rtecho.WS._construct();

/*Usage*/
// with params
/*
var prms = new Rtecho.NV.Collection;
prms.Add("stateId", "32");
var rc = new Rtecho.WS.RequestController("http://www.rtecho.com/rtecho.asmx");
rc.GetList("GetCities", prms, "CityInfo", ProcessCities);
function ProcessCities(list)
{
    for(var i in list)
    {
        alert(list[i].Name + " = > " + list[i].Key);
    }
}
*/

// without params
/*
rc.GetList("GetSpoStates", null, "StateInfo", ProcessStates);
function ProcessStates(list)
{
    for(var i in list)
    {
        alert(list[i].Name + " ===> " + list[i].Key);
    }
}
*/
