var ROOT = "/";
/*
var uid = function() {
    if (!arguments.callee.prototype.counter)
        arguments.callee.prototype.counter = 1;
    return 'uid' + arguments.callee.prototype.counter++;
}
var $ = function(id) {
    if (!id)
        return null;
    return document.getElementById(id);
}
var $$ = function(el, cl, inn) {
    var res = document.createElement(el);
    if (cl)
        res.className = cl;
    if (inn)
        res.innerHTML = inn;
    res.id = uid();
    return res;
}
var $$text = function(text) {
    return document.createTextNode(text);
}

*/
var ONLOAD = [];

var Base = {};

Base.Dom = {};
Base.Dom.addEvent = function(el, sType, wrappedFn) {
    if (!el)
        return;
    if (el.addEventListener) {
        el.addEventListener(sType, wrappedFn, false);
    } else if (el.attachEvent) {
        el.attachEvent("on" + sType, wrappedFn);
    } else {
        el['on' + sType] = wrappedFn;
    }
}
Base.Dom.removeEvent = function(el, sType, fn) {
    if (el.removeEventListener) {
        el.removeEventListener(sType, fn, false);
    } else if (el.detachEvent) {
        el.detachEvent("on" + sType, fn);
    } else {
        el['on' + sType] = null;
    }
}
Base.Dom.center = function(element) {

    var displayW = Base.Dom.getViewportWidth();
    var displayH = Base.Dom.getViewportHeight();
    var displayX = Base.Dom.getHorizontalScroll();
    var displayY = Base.Dom.getVerticalScroll();

    var thisWidth = element.offsetWidth;
    var thisHeight = element.offsetHeight;
    var ox = displayX + (displayW - thisWidth ) / 2 ;
    var oy = displayY + (displayH - thisHeight ) / 2 ;
    ox = Math.max(ox, 0)
    oy = Math.max(oy, 0)
    element.style.left = ox + 'px'
    element.style.top = oy + 'px'
}
Base.Dom.transparency = function(element, transpPct) {
    try {
        element.style['opacity'] = (transpPct / 100);
    } catch(e) {
    }
    try {
        element.style['-moz-opacity'] = (transpPct / 100);
    } catch(e) {

    }
    try {
        element.style['filter'] = "alpha( opacity = " + transpPct + " )";
    } catch(e) {

    }
}
Base.Dom.initGeometry = function() {
    if (window.screenLeft) {
        this.getWindowX = function() {
            return window.screenLeft;
        };
        this.getWindowY = function() {
            return window.screenTop;
        };
    }
    if (window.screenX) {
        this.getWindowX = function() {
            return window.screenX;
        };
        this.getWindowY = function() {
            return window.screenY;
        };
    }
    if (document.documentElement && document.documentElement.clientWidth) {
        this.getViewportWidth = function() {
            return document.documentElement.clientWidth;
        };
        this.getViewportHeight = function() {
            return document.documentElement.clientHeight;
        };
        this.getHorizontalScroll = function() {
            return document.documentElement.scrollLeft;
        };
        this.getVerticalScroll = function() {
            return document.documentElement.scrollTop;
        };
    } else  if (window.innerWidth) {
        this.getViewportWidth = function() {
            return window.innerWidth;
        };
        this.getViewportHeight = function() {
            return window.innerHeight;
        };
        this.getHorizontalScroll = function() {
            return window.pageXOffset;
        };
        this.getVerticalScroll = function() {
            return window.pageYOffset;
        };
    } else if (document.body.clientWidth) {
        this.getViewportWidth = function() {
            return document.body.clientWidth;
        };
        this.getViewportHeight = function() {
            return document.body.clientHeight;
        };
        this.getHorizontalScroll = function() {
            return document.body.scrollLeft;
        };
        this.getVerticalScroll = function() {
            return document.body.scrollTop;
        };
    }
    if (document.documentElement && document.documentElement.scrollWidth) {
        this.getDocumentWidth = function() {
            return document.documentElement.scrollWidth;
        };
        this.getDocumentHeight = function() {
            return document.documentElement.scrollHeight;
        };
    } else if (document.body.scrollWidth) {
        this.getDocumentWidth = function() {
            return document.body.scrollWidth;
        };
        this.getDocumentHeight = function() {
            return document.body.scrollHeight;
        };
    }
}
Base.Dom.addEvent = function(el, sType, wrappedFn) {
    if (!el)
        return;
    if (el.addEventListener) {
        el.addEventListener(sType, wrappedFn, false);
    } else if (el.attachEvent) {
        el.attachEvent("on" + sType, wrappedFn);
    } else {
        el['on' + sType] = wrappedFn;
    }
}
Base.Dom.append = function(parent, child) {
    if (child instanceof Array) {
        for (var i in child)
            parent.appendChild(child[i]);
    } else {
        parent.appendChild(child);
    }
}
Base.Dom.getEventX = function(ev, el) {
    var x = ev.pageX;
    if (!x && 0 !== x) {
        x = ev.clientX || 0;
        x += Base.Dom.getHorizontalScroll();
    }
    return x;
}
Base.Dom.getEventY = function(ev, el) {
    var y = ev.pageY;
    if (!y && 0 !== y) {
        y = ev.clientY || 0;
        y += Base.Dom.getVerticalScroll();
    }
    return y;
}



//================================================================

Base.XML = {};

Base.XML.parseFromString = function(text) {
    if (typeof DOMParser != "undefined") {
        return (new DOMParser()).parseFromString(text, "application/xml");
    } else if (typeof ActiveXObject != "undefined") {
        var doc = this.newDocument();
        // Create an empty document
        doc.loadXML(text);
        // Parse text into it
        return doc;
        // Return it
    } else {
        var url = "data:text/xml;charset=utf-8," + encodeURIComponent(text);
        var request = new XMLHttpRequest();
        request.open("GET", url, false);
        request.send(null);
        return request.responseXML;
    }
}
Base.XML.parse = function(xml) {
    var root = xml.documentElement;
    return this.value(xml.documentElement);
}
Base.XML.simpleChild = function(node, name, value) {
    var doc = node.ownerDocument;
    var el = doc.createElement(name);
    node.appendChild(el);
    if (value) {
        var v = doc.createTextNode(value);
        el.appendChild(v);
    }
    return el;
}
Base.XML.text_value = function(node) {
    return node.text ? node.text : node.textContent;
}
Base.XML.vs = function(node, child) {
    return "" + Base.XML.text_value(node.getElementsByTagName(child)[0].childNodes[0]);
}
Base.XML.vn_s = function(node, child) {
    return Number(Base.XML.text_value(node.childNodes[0]));
}
Base.XML.vn = function(node, child) {
    return Number(Base.XML.text_value(node.getElementsByTagName(child)[0].childNodes[0]));
}
Base.XML.vn_s = function(node, child) {
    return Number(Base.XML.text_value(node.childNodes[0]));
}
Base.XML.value = function(root) {
    if (root.nodeType == root.TEXT_NODE)
        return this.text_value(root);
    var o = {};
    for (var i = 0; i < root.childNodes.length; i++) {
        var node = root.childNodes[i];
        var name = node.nodeName;
        if (!(name in o))
            o[name] = [];
        o[name].push(this.value(node));
    }

    for (var p in o) {
        if (o[p].length == 1)
            o[p] = o[p][0];
    }
    o.toString = function() {
        var all = '(';
        for (var p in o) {
            if (o[p] == arguments.callee)
                continue;
            all += all == '(' ? '' : '&';
            all += p + "=" + o[p];
        }
        return all + ')';
    }
    return o;
}
Base.XML.newDocument = function(rootTagName, namespaceURL) {
    if (!rootTagName)
        rootTagName = "";
    if (!namespaceURL)
        namespaceURL = "";
    if (document.implementation && document.implementation.createDocument) {
        return document.implementation.createDocument(namespaceURL, rootTagName, null);
    } else {
        var doc = new ActiveXObject("MSXML2.DOMDocument");
        if (rootTagName) {
            var prefix = "";
            var tagname = rootTagName;
            var p = rootTagName.indexOf(':');
            if (p != -1) {
                prefix = rootTagName.substring(0, p);
                tagname = rootTagName.substring(p + 1);
            }
            if (namespaceURL) {
                if (!prefix)
                    prefix = "a0";
            } else prefix = "";
            var text = "<" + (prefix ? (prefix + ":") : "") + tagname +
                       (namespaceURL
                               ? (" xmlns:" + prefix + '="' + namespaceURL + '"')
                               : "") +
                       "/>";
            doc.loadXML(text);
        }
        return doc;
    }
};
Base.XML.serialize = function(node) {
    var ret = null;
    if (node == null)
        return '';
    if (typeof XMLSerializer != 'undefined') {
        ret = (new XMLSerializer()).serializeToString(node);
    } else if (node.xml) {
        ret = node.xml;
    } else {
        throw "Serialize not supported";
    }
    return ret;
}
Base.XML.setValue = function(node, value) {
    if ('textContent' in node)
        node.textContent = value;
    else
        node.text = value;
}
Base.XML.addSimpleChild = function (doc, node, childname, childvalue) {
    var el = doc.createElement(childname);
    Base.XML.setValue(el, childvalue);
    node.appendChild(el);
}
Base.XML.addEmptyChild = function (doc, node, childname) {
    var el = doc.createElement(childname);
    node.appendChild(el);
    return el;
}

//================================================================

Base.Event = {};
Base.Event.stopEvent = function(event) {
    this.stopEvent(event);
    this.preventDefault(event);
}
Base.Event.stopPropagation = function(ev) {
    if (ev.stopPropagation) {
        ev.stopPropagation();
    } else {
        ev.cancelBubble = true;
    }
};
Base.Event.preventDefault = function(ev) {
    if (ev.preventDefault) {
        ev.preventDefault();
    } else {
        ev.returnValue = false;
    }
}

//================================================================

Base.Modality = {};
Base.Modality._mask = null;
Base.Modality.disableDocument = function() {

}
Base.Modality.enableDocument = function() {

}
Base.Modality.assertMask = function() {
    if (this._mask == null) {
        this._mask = $$('div', '&nbsp;')
    }
}

//================================================================

Base.Misc = {}
Base.Misc.objectToHTML = function(o) {
    var div = $$('div');
    div.style.marginLeft = '10px';
    for (var p in o) {
        var d = $$('div');
        d.appendChild($$('div', null, p));
        d.appendChild($$('div', null, o[p]));
        div.appendChild(d);
    }
    return div;
}
Base.Misc.defString = function() {
    var all = '(';
    var o = this;
    for (var p in o) {
        if (o[p] == arguments.callee || !(typeof o[p] == 'function'))
            continue;
        all += all == '(' ? '' : '&';
        all += p + "=" + (typeof o[p] == 'function' ? 'function' : 'object') + '\n';
    }
    return all + ')';
}
Base.Misc.unescapedQuery = function(o) {
    var query = '';
    for (var p in o) {
        if (o[p] != null) {
            query += query.length ? '&' : '?';
            query += p + "=" + o[p];
        }
    }
    return query;
}
Base.Misc.trim = function(txt) {
    while (true) {
        var first = txt.substring(0, 1);
        if (first != " " && first != '\n')
            break;
        txt = txt.substring(1);
    }
    while (true) {
        var first = txt.substring(txt.length - 1);
        if (first != " " && first != '\n')
            break;
        txt = txt.substring(0, txt.length - 2);
    }
    return txt;
}
Base.Misc.stringCompare = function(s1, s2) {
    if (s1 == s2)
        return 0;
    for (var i = 0; i < Math.min(s1.length, s2.length); i++) {
        if (s1.charAt(i) == s2.charAt(i))
            continue;
        return s1.charAt(i) < s2.charAt(i) ? -1 : 1;
    }
    return s1.length < s2.length ? -1 : 1;
}
Base.Misc.createViewportPanel = function() {
    var div = $$('div');
    div.style.position = 'absolute';

    div.toSize = function() {
        div.style.left = Base.Dom.getHorizontalScroll() + 'px';
        div.style.top = Base.Dom.getVerticalScroll() + 'px';
        Base.Misc.animate(this, 'width', 20, 10, this.offsetWidth, Base.Dom.getViewportWidth() - 10)
        Base.Misc.animate(this, 'height', 20, 10, this.offsetHeight, Base.Dom.getViewportHeight() - 10)
    }
    div.toCenter = function() {
        div.style.width = Base.Dom.getViewportWidth() + 'px';
        div.style.height = Base.Dom.getViewportHeight() + 'px';
        Base.Misc.animate(this, 'top', 20, 10, this.offsetTop, Base.Dom.getVerticalScroll())
        Base.Misc.animate(this, 'left', 20, 10, this.offsetLeft, Base.Dom.getHorizontalScroll())
    }
    div.updateSize = function() {
        if (div.timeout != null) {
            clearTimeout(div.timeout)
            div.timeout = null;
        }
        div.timeout = setTimeout(function() {
            div.toSize();
            div.timeout = null;
        }, 100);
    }
    div.updateScroll = function() {
        if (div.timeout != null) {
            clearTimeout(div.timeout)
            div.timeout = null;
        }
        div.timeout = setTimeout(function() {
            div.toCenter();
            div.timeout = null;
        }, 100);
    }
    Base.Dom.addEvent(window, 'scroll', function() {
        div.updateScroll();
    })
    Base.Dom.addEvent(window, 'resize', function() {
        div.updateSize();
    })
    return div;
}

Base.Misc.popup = function(element, time) {
    var thread = 0;

    var timeout = Math.max(1, time / 100);
    var iterations = time / timeout;
    var dt = 100 / iterations;
    var index = dt;

    var next = function() {
        if (index > 100 || element.style.display == 'none') {
            if (thread) {
                clearTimeout(thread);
                thread = null;
            }
            return;
        }
        var index1 = index;

        Base.Dom.transparency(element, index1)
        index += dt;
    }
    thread = setInterval(next, timeout);
}
Base.Misc.toTextArea = function(text) {
    document.body.appendChild($$("textarea", null, text));
}

//================================================================

Base.Widjet = {};
Base.Widjet.ConnectionWaiter = function() {
    this.create();
}
Base.Widjet.ConnectionWaiter.prototype.create = function() {
    this.div = $$('div', 'waiter');
    //this.div.innerHTML = 'Processing...<br/>Please wait...'
    document.body.appendChild(this.div);
}
Base.Widjet.ConnectionWaiter.prototype.startWait = function() {
    Base.Dom.transparency(this.div, 0);
    this.div.style.display = 'block';
    var displayW = Base.Dom.getViewportWidth();
    var displayH = Base.Dom.getViewportHeight();
    var displayX = Base.Dom.getHorizontalScroll();
    var displayY = Base.Dom.getVerticalScroll();
    this.div.style.left = displayX + (displayW - this.div.offsetWidth) / 2 + 'px';
    this.div.style.top = displayY + (displayH - this.div.offsetHeight) / 2 + 'px';
    Base.Misc.popup(this.div, 1000);
}
Base.Widjet.ConnectionWaiter.prototype.stopWait = function() {
    this.div.style.display = 'none';
}
Base.Widjet.ConnectionWaiter.getInstance = function() {
    if (!this.INSTANCE)
        this.INSTANCE = new Base.Widjet.ConnectionWaiter();
    return this.INSTANCE;
}

//================================================================

Base.Widjet.Message = function() {
    this.create();
}
Base.Widjet.Message.prototype.create = function() {
    var containter = $$('div', 'messageholder')

    var iframe = $$('iframe', "msgframe");
    iframe.frameBorder = 0;

    var msg = $$('div', 'message');
    var shad = $$('div', 'shaddow', '&nbsp;');
    containter.appendChild(shad)
    containter.appendChild(msg)

    Base.Dom.transparency(shad, 40);
    document.body.appendChild(containter);
    document.body.appendChild(iframe);

    var msgHrd = $$('div');
    var buttonHdr = $$('div');
    msg.appendChild(msgHrd)
    msgHrd.style.padding = '1em';

    msg.appendChild(buttonHdr)
    var button = $$('button', null, 'OK')
    buttonHdr.appendChild(button)

    var tthis = this;
    Base.Dom.addEvent(button, 'click', function() {
        tthis.hideMessage();
    })

    this.div = containter;
    this.message = msg;
    this.messageHolder = msgHrd;
    this.shaddow = shad;
    this.button = button;
    this.iframe = iframe;
}
Base.Widjet.Message.prototype.showMessage = function(message) {
    this.messageHolder.innerHTML = message;
    this.div.style.display = 'block';
    this.iframe.style.display = 'block';
    this.div.style.width = this.message.offsetWidth + 'px';
    this.div.style.height = this.message.offsetHeight + 'px';
    var displayW = Base.Dom.getViewportWidth();
    var displayH = Base.Dom.getViewportHeight();
    var displayX = Base.Dom.getHorizontalScroll();
    var displayY = Base.Dom.getVerticalScroll();
    this.div.style.left = displayX + (displayW - this.div.offsetWidth) / 2 + 'px';
    this.div.style.top = displayY + (displayH - this.div.offsetHeight) / 2 + 'px';
    //    this.div.style.display = 'block';

    this.iframe.style.width = this.div.offsetWidth + 'px';
    this.iframe.style.height = this.div.offsetHeight + 'px';
    this.iframe.style.top = this.div.style.top;
    this.iframe.style.left = this.div.style.left;

    this.shaddow.style.width = this.message.offsetWidth + 'px'
    this.shaddow.style.height = this.message.offsetHeight + 'px'

    this.button.focus();
}
Base.Widjet.Message.prototype.hideMessage = function() {
    this.div.style.display = 'none';
    this.iframe.style.display = 'none';
}
Base.Widjet.Message.getInstance = function() {
    if (!this.INSTANCE)
        this.INSTANCE = new Base.Widjet.Message();
    return this.INSTANCE;
}

//================================================================

Base.Connect = {};

Base.Connect.openBigTarget = function(target, query, anchor) {
    query.___target___ = target;
    var url = this.getMainURI() + this.query(query) + (anchor ? "#"+anchor : "");
    window.open(url)
}
Base.Connect.openTarget = function(target, query) {
    query.___target___ = target;
    var url = this.getMainURI() + this.query(query);
    var params = 'toolbar=1,scrollbars=1,location=1,statusbar=1,menubar=1,resizable=1,width=1000,height=520'
    window.open(url, uid(), params)
}
Base.Connect.postTarget = function(target, query, ss, ff, silent) {
    query.___target___ = target
//    query.___method___ = 'postTarget';
    this.post(this.getMainURI(), query, ss, ff, silent)
}
Base.Connect.getTarget = function(target, query, ss, ff) {
    query.___target___ = target;
//    query.___method___ = 'getTarget';
    this.do_request(this.getMainURI(), query, ss, ff, 'get')
}
Base.Connect.submitTarget = function(target, query, method, anchor) {
    query.___target___ = target;
//    query.___method___ = 'submitTarget';
    this.submit(this.getMainURI(), query, method, anchor)
}
Base.Connect.query = function(o, b) {
    var query = '';
    for (var p in o) {
        if (o[p] != null) {
            query += query.length ? '&' : (b ? '' : '?');
            query += p + "=" + encodeURIComponent(o[p]);
        }
    }
    return query;
}
Base.Connect.queryNoEscape = function(o, b) {
    var query = '';
    for (var p in o) {
        if (o[p] != null) {
            query += query.length ? '&' : (b ? '' : '?');
            query += p + "=" + o[p];
        }
    }
    return query;
}
Base.Connect.post = function(path, query, ss, ff, silent) {
    if (!silent)
        Base.Widjet.ConnectionWaiter.getInstance().startWait();

    var callback = {
        end:function() {
            try {
                if (!silent)
                    Base.Widjet.ConnectionWaiter.getInstance().stopWait();
            } catch(e) {
                slickAlert('Base.Widjet.ConnectionWaiter.getInstance().stopWait')
            }
        },
        success : function(o) {
            this.end();

            if (o.redirectTarget) {
                Base.Connect.submitTarget(o.redirectTarget, {});
                return;
            }

            try {
                if (ss)
                    ss(o);
            } catch(e) {
                slickAlert("Error while processing \n" + e)
            }
        },
        failure : function(o) {
            this.end();
            try {
                if (ff)
                    ff(o);
            } catch(e) {
                slickAlert(e);
            }
        }
    }
    var qq = this.query(query, true);
//    var qq = this.queryNoEscape(query, true);
    Ajax.Connect.asyncRequest('post', path, callback, qq);
}
Base.Connect.request = function(path, query, ss, ff) {
    this.do_request(path, query, ss, ff, 'get')
}
Base.Connect.do_request = function(path, query, ss, ff, method) {
    var url = path + this.query(query);
    Base.Widjet.ConnectionWaiter.getInstance().startWait();

    var callback = {
        end:function() {
            try {
                Base.Widjet.ConnectionWaiter.getInstance().stopWait();
            } catch(e) {
                slickAlert('Base.Widjet.ConnectionWaiter.getInstance().stopWait')
            }
        },
        success : function(o) {
            this.end();

            if (o.redirectTarget) {
                Base.Connect.submitTarget(o.redirectTarget, {});
                return;
            }

            try {
                if (ss)
                    ss(o);
            } catch(e) {
                slickAlert("Error while processing\n" + e)
            }
        },
        failure : function(o) {
            this.end();
            try {
                if (ff)
                    ff(o);
            } catch(e) {
                slickAlert(e);
            }
        }
    }
    Ajax.Connect.asyncRequest(method, url, callback)
}
Base.Connect.defaultAlert = function(o) {
    slickAlert(o.responseText)
}
Base.Connect.defaultError = function(o) {
    document.body.innerHTML = o.responseText;
}
Base.Connect.submit = function(path, query, method, anchor) {
    if (!method)
        method = 'post'

    var form = $$('form')
    if (anchor)
        form.action = path + "#" + anchor;
    else
        form.action = path;

    form.method = method;
    form.style.display = 'none';

    for (var prop in query) {
        var textarea = $$('textarea');
        textarea.value = query[prop];
        textarea.name = prop;
        form.appendChild(textarea);
    }
    document.body.appendChild(form);
    form.submit();
}

Base.Dom.initGeometry();

//================================================================


var slickAlert = function(message) {
    alert(message)
}
Base.Dom.addEvent(window, 'load', function() {
    for (var i = 0; i < ONLOAD.length; i++) {
        try {
            ONLOAD[i]();
        } catch(e) {
            alert(ONLOAD[i])
        }
    }
});
ONLOAD.push(function() {
    slickAlert = function(message) {
        Base.Widjet.Message.getInstance().showMessage(message);
    }
})
ONLOAD.push(function() {
    Base.Dom.initGeometry();
    Base.Dom.initGeometry = function() {
    }
});

