/* Common JavaScript library */
/* 1) Small DOM helpers */
/* 2) Content loader (CL) */

var IE = document.all ? 1 : 0;

$ = function(element) {
    if (arguments.length > 1) {
        for (var i = 0, elements = [], length = arguments.length; i < length; i++)
            elements.push($(arguments[i]));
        return elements;
    } else {
        return document.getElementById(element);
    }
}

$new = function(params, parent) {
    var tag = params['tag'] || 'div';
    var newEl = document.createElement(tag);
    for (var paramName in params) {
        if ((paramName != 'tag') && (paramName != 'text')
                && (!paramName.match(/^on\w+/))) {
            newEl[paramName] = params[paramName];
        }
        if (paramName.match(/^on(\w+)/)) {
            var eventName = RegExp.$1;
            $attachEvent(newEl, eventName, params[paramName]);
        }
    }
    if (params['text'] != null) {
        newEl.appendChild($text(params['text']));
    }
    if (parent != null) {
        parent.appendChild(newEl);
    }
    return newEl;
}

$text = function(string) {
    return document.createTextNode(string);
}

$clearDOM = function(el) {
    while (el.childNodes.length > 0) {
        el.removeChild(el.firstChild);
    }
}

$addClass = function(node, className) {
    $removeClass(node, className);
    node.className += ' ' + className;
}

$removeClass = function(node, className) {
    var classes = node.className.split(' ');
    for (var i = 0; i < classes.length; i++) {
        if (classes[i] == className) {
            classes.splice(i, 1);
        }
    }
    node.className = classes.join(' ');
}

$style = function(node, args) {
    for (var arg in args) {
        if ((arg == 'left') || (arg == 'top') || (arg == 'width')
                || (arg == 'height') || (arg == 'right') || (arg == 'bottom'))
            args[arg] += 'px';
        node.style[arg] = args[arg];
    }
}

$point = function(x, y) {
    this.x = x;
    this.y = y;
}
$position = function(node, toNode) {
    var el = node;
    var x = 0;
    var y = 0;
    while ((el) && (el != toNode)) {
        if (el.offsetLeft) {
            x += el.offsetLeft;
        }
        if (el.offsetTop) {
            y += el.offsetTop;
        }
        el = el.offsetParent;
    }
    return new $point(x, y);
}
$attachEvent = function(object, event, method, methodId) {
    if (!methodId) {
        methodId = '';
    }
    object['event_' + event + methodId] = function(event) {
        method.apply(object, [event]);
    };
    if (typeof(object['addEventListener']) == 'function') {
        object.addEventListener(event, object['event_' + event + methodId],
                false);
    } else {
        object.attachEvent('on' + event, object['event_' + event + methodId]);
    }
}

$detachEvent = function(object, event, methodId) {
    if (!methodId) {
        methodId = '';
    }
    if (typeof(object['removeEventListener']) == 'function') {
        object.removeEventListener(event, object['event_' + event + methodId],
                false);
    } else {
        object.detachEvent('on' + event, object['event_' + event + methodId]);
    }
}
JS = new Object();
// Browser checking
// TODO: write more if need
JS.agent = navigator.userAgent;
if (JS.agent.match(/MSIE\s+(\d+)/)) {
    JS.IE = true;
    JS.IE_Version = RegExp.$1;
    if (JS.IE_Version < 7)
        JS.IE_OLD = true;
}

JS.KHTML = JS.agent.match(/KHTML/);
JS.Opera = JS.agent.match(/Opera/);
JS.Gecko = (!JS.KHTML && JS.agent.match(/Gecko/));
JS.DOM = document.getElementById ? true : false;

/* array copy ----------- */
function $A(source) {
    var ret = [];
    ret = source.slice(0, source.length);
    return ret;
}

/* Ajax Loader */
CL = new Object();
CL.READY_STATE_UNINITIALIZED = 0;
CL.READY_STATE_LOADING = 1;
CL.READY_STATE_LOADED = 2;
CL.READY_STATE_INTERACTIVE = 3;
CL.READY_STATE_COMPLETE = 4;

CL.loader = function(component, url, method, requestParams) {
    this.component = component;
    this.url = url;
    this.requestParams = requestParams;
    this.method = method;
}

CL.loader.prototype = {
    getTransport : function() {
        var transport;
        if (window.XMLHttpRequest) {
            transport = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            try {
                transport = new ActiveXObject('Msxml2.XMLHTTP');
            } catch (err) {
                transport = new ActiveXObject('Microsoft.XMLHTTP');
            }
        }
        return transport;
    },
    sendRequest : function() {
        var requestParams = [];
        for (var i = 0; i < arguments.length; i++) {
            requestParams.push(arguments[i]);
        }
        var request = this.getTransport();
        request.open(this.method, this.url, true);
        request.setRequestHeader('Content-Type',
                'application/x-www-form-urlencoded');
        var oThis = this;
        request.onreadystatechange = function() {
            oThis.handleAjaxResponse(request);
        }
        request.send(this.queryString(requestParams));
    },
    queryString : function(args) {
        var requestParams = [];
        for (var i = 0; i < this.requestParams.length; i++) {
            requestParams.push(this.requestParams[i]);
        }
        for (var i = 0; i < args.length; i++) {
            requestParams.push(args[i]);
        }
        var queryString = "";
        if (requestParams && requestParams.length > 0) {
            for (var i = 0; i < requestParams.length; i++) {
                queryString += requestParams[i] + '&';
            }
            queryString = queryString.substring(0, queryString.length - 1);
        }
        return queryString;
    },
    handleAjaxResponse : function(request) {
        if (request.readyState == CL.READY_STATE_COMPLETE) {
            if (this.isSuccess(request)) {
                this.component.ajaxUpdate(request);
            } else {
                this.component.handleError(request);
            }
        }
        if (request.readyState == CL.READY_STATE_LOADING) {
            if (typeof(this.component.ajaxLoading) == 'function') {
                this.component.ajaxLoading(request);
            }
        }
    },
    isSuccess : function(request) {
        return request.status == 0
                || (request.status >= 200 && request.status < 300);
    }
};

CL.xmlSet = function(xmlElement) {
    var len = xmlElement.childNodes.length;
    for (var i = 0; i < len; i++) {
        var attrName = xmlElement.childNodes[i].tagName;
        var attrValue = CL.textContent(xmlElement.childNodes[i]);
        this[attrName] = attrValue;
    }
}

CL.textContent = function(xmlElement) {
    if (xmlElement.text != undefined)
        return xmlElement.text;
    else if (xmlElement.textContent != undefined)
        return xmlElement.textContent;
    else if (xmlElement.firstChild != undefined)
        return xmlElement.firstChild.nodeValue;
}

var _urlCache = {};

function constructURLString(params) {
    var url = '/';
    var sParams = {};
    for (var key in params)
        sParams[key] = params[key];
    var _waiting = false;
    if (params['action']) {
        url = '/' + params['action'] + '/';
        delete sParams['action'];
    } else if ((params['module']) && (params['interface'])) {
        _key = params['module'] + ',' + params['interface'];
        if (_urlCache[_key]) {
            url = _urlCache[_key];
            delete sParams['module'];
            delete sParams['interface'];
        }
    } else if (params['node_id']) {
        _key = params['node_id'];
        if (_urlCache[_key]) {
            url = _urlCache[_key];
            delete sParams['node_id'];
        }
    }
    var j = '?'
    for (var key in sParams) {
        url += j + encodeURIComponent(key) + '=' + encodeURIComponent(sParams[key]);
        j = '&';
    }
    return url;
}


function constructURLCache(params, callback, errorCallback) {
    var so = new Object();
    var loader = new CL.loader(so, '/fetch/', 'POST', ['order=geturl']);
    var _key = '';
    if ((params['module']) && (params['interface'])) {
        _key = params['module'] + ',' + params['interface'];
        if (_urlCache[_key])
            return;
        loader.requestParams.push(
            'module=' + encodeURIComponent(params['module']),
            'interface=' + encodeURIComponent(params['interface'])
        );
    } else if (params['node_id']) {
        _key = params['node_id'];
        if (_urlCache[_key])
            return;
        loader.requestParams.push('node_id=' + encodeURIComponent(params['node_id']));
    } else {
        return;
    }
    so.handleError = function() {
        if (typeof(errorCallback) === 'function')
            errorCallback();
    }
    so.ajaxUpdate = function(request) {
        if (request.responseXML) {
            var urlXML = request.responseXML.getElementsByTagName('url')[0];
            if (urlXML) {
                var url = CL.textContent(urlXML);
                if (url) {
                    _urlCache[_key] =  url;
                    if (typeof(callback) === 'function')
                        callback(url);
                    return;
                }
            }
        }
        so.handleError();
    }
    loader.sendRequest();
}

function SetDialogWindowUp(e, diaWin) {
    if (diaWin && !diaWin.closed) {
        if (e)
            e.preventDefault();
        diaWin.focus();
        return false;
    }
}

function Pack(arr) {
    var resStr, key;
    resStr = '';
    for (key in arr)
        resStr += escape(key) + "=" + escape(arr[key]) + "&";
    return resStr;
}

function UnPack(str) {
    var resArr, pairsArr, onePairArr, i;

    resArr = new Array();
    if (str) {
        pairsArr = str.split("&");
        onePairArr = new Array();
        for (i = 0; i < pairsArr.length; i++) {
            onePairArr = pairsArr[i].split("=");
            resArr[unescape(onePairArr[0])] = unescape(onePairArr[1]);
        }
    }
    return resArr;
}

function CancelEvent(e) {
    if (IE)
        window.event.result = false;
    else
        e.preventDefault();
    return false;
}

function SerializeForm(form) {
    var paramArray = new Array(), formElement, i;
    for (i = 0; i < form.elements.length; i++) {
        formElement = form.elements[i];
        if (formElement.type == "text" || formElement.type == "radio"
                || formElement.type == "checkbox"
                || formElement.type == "hidden"
                || formElement.type == "textarea") {
            paramArray[formElement.id] = formElement.value;
        } else if (formElement.type.search("select") != -1) {
            paramArray[formElement.id] = formElement.options[formElement.selectedIndex].value;
        } else
            continue;
    }
    return Pack(paramArray);
}

function CancelDialog() {
    window.returnValue = null;
    window.close();
}

function DoneDialog() {
    if (window.opener)
        window.opener.UnblockEvents();
}

function SubmitDialog(dialogValuesString) {
    if (window.ProcessDialog)
        window.ProcessDialog(dialogValuesString);
    window.close();
}

function ParseKeyPressed(e) {
    var event = IE ? window.event : e;
    if (event && (event.keyCode == 27))
        CancelDialog();
}

function ReportError(msg, url, line) {
    return 0;
    // TODO: Write error handler if need
}

function GetArguments() {
    return DialogArgumentsString;
}

function trSLink(form) {
    var res = form['object_name'].value.toLowerCase();
    var ru = [/ш/gi, /щ/gi, /п/gi, /д/gi, /ь/gi, /ч/gi, /е/gi, /в/gi, /б/gi,
            /у/gi, /а/gi, /й/gi, /р/gi, /к/gi, /т/gi, /н/gi, /ц/gi, /м/gi,
            /о/gi, /ж/gi, /з/gi, /и/gi, /ъ/gi, /с/gi, /ф/gi, /л/gi, /я/gi,
            /ё/gi, /г/gi, /х/gi, /э/gi, /ы/gi, /ю/gi];
    var en = ['sh', 'shh', 'p', 'd', '', 'ch', 'e', 'v', 'b', 'u', 'a', 'j',
            'r', 'k', 't', 'n', 'c', 'm', 'o', 'zh', 'z', 'i', '', 's', 'f',
            'l', 'ja', 'jo', 'g', 'kh', 'eh', 'y', 'ju'];
    for (var i = 0; i < ru.length; i++)
        res = res.replace(ru[i], en[i]);
    res = res.replace(/\s+/g, '-');
    res = res.replace(/[^A-Za-z0-9_\-]/g, '');
    res = res.replace(/\-+/g, '-');
    form['slink'].value = res;
}

function ruSLink(form) {
    var res = form['object_name'].value;
    //.toLowerCase();
    res = res.replace(/\s+/g, '-');
    //res = res.replace(/[^A-Za-z0-9_\-]/g, '');
    res = res.replace(/\-+/g, '-');
    form['slink'].value = res;
}

function SmallSet(a) {
    if (a && (typeof a == 'array' || typeof a == 'object'))
        this.container = a.slice()
    else
        this.container = new Array();
    this.length = this.container.length;
}

SmallSet.prototype.contains = function(value) {
    for (var i = 0; i < this.length; i++)
        if (value == this.container[i])
            return true;
    return false;
}

SmallSet.prototype.add = function(value) {
    if (!this.contains(value)) {
        this.container.push(value);
        this.length = this.container.length;
    }
}

SmallSet.prototype.del = function(value) {
    for (var i = 0; i < this.length; i++)
        if (value == this.container[i]) {
            this.container.splice(i, 1);
            this.length = this.container.length;
            return;
        }
}

window.defineWindowMethod = function(name, func) {
    window['__WIN_' + name + '_METHOD'] = func;
}

