var ERROR_BASE                  = 1000;
var ERROR_DOM_NODE_NOT_FOUND    = ERROR_BASE + 1;
var ERROR_WINDOW_UNKNOWN_NAME   = ERROR_BASE + 2;
var ERROR_WRONG_DOM_PATH        = ERROR_BASE + 3;

var WINDOW_DESK_ERROR_BASE      = 10000
var WINDOW_DESK_ERROR_WRITE     = WINDOW_DESK_ERROR_BASE + 2;
var WINDOW_DESK_ERROR_PASSWORD  = WINDOW_DESK_ERROR_BASE + 6;
var WINDOW_DESK_ERROR_READ      = WINDOW_DESK_ERROR_BASE + 7;
var ERROR_WRONG_CAPTCHA         = WINDOW_DESK_ERROR_BASE + 9;

function Exception(code, message)
{
    this._message = message;
    this._code = code;

    this.toString = function()
    {
        return '[' + this._code + '] ' + this._message;
    }

    this.getCode = function()
    {
        return this._code;
    }
}

function _(id)
{
    var o = document.getElementById(id);
    if (!o) {
        throw new Exception(ERROR_DOM_NODE_NOT_FOUND, "'" + id + "'" + ' - this id does not exit in DOM');
    }
    return o;
}

function viewportDimensions()
{
    var x, y;
    if (self.innerHeight) { // all except Explorer
    	x = self.innerWidth;
    	y = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
    	x = document.documentElement.clientWidth;
    	y = document.documentElement.clientHeight;
    }
    else if (document.body) { // other Explorers
    	x = document.body.clientWidth;
    	y = document.body.clientHeight;
    }

    return {'width': x, 'height': y};
}

function viewportOffset()
{
    var x, y;
    if (self.pageYOffset) { // all except Explorer
    	x = self.pageXOffset;
    	y = self.pageYOffset;
    }
    else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
    	x = document.documentElement.scrollLeft;
    	y = document.documentElement.scrollTop;
    }
    else if (document.body) { // all other Explorers
    	x = document.body.scrollLeft;
    	y = document.body.scrollTop;
    }

    return {'offsetX': x, 'offsetY': y};
}

function documentDimensions()
{
    var x, y;
    var test1 = document.body.scrollHeight;
    var test2 = document.body.offsetHeight;

    if (test1 > test2) { // all but Explorer Mac
    	x = document.body.scrollWidth;
    	y = document.body.scrollHeight;
    } else { // Explorer Mac; would also work in Explorer 6 Strict, Mozilla and Safari
    	x = document.body.offsetWidth;
    	y = document.body.offsetHeight;
    }

    return {'width': x, 'height': y};
}

function eventPosition(e)
{
    var posx = 0;
	var posy = 0;

	var isOpera = (navigator.userAgent.indexOf('Opera') != -1);
    var isIE = (!isOpera && navigator.userAgent.indexOf('MSIE') != -1);

	if (!e) var e = window.event;

	if (e.pageX || e.pageY) {
		posx = e.pageX;
		posy = e.pageY;
	} else if (e.clientX || e.clientY) {
		posx = e.clientX;
		posy = e.clientY;
		if (isIE) {
			posx += document.body.scrollLeft;
			posy += document.body.scrollTop;
		}
	}

	return {'x': posx, 'y': posy};
}

var sUserAgent = navigator.userAgent;
var isIE = sUserAgent.indexOf("compatible") > -1 && sUserAgent.indexOf("MSIE") > -1 && sUserAgent.indexOf("Opera") == -1;
var isWin = (navigator.platform == "Win32") || (navigator.paltform == "Windows");

var jEvent = {
    addEvent: function(obj, type, fn, once)
    {
        if (once && obj['event_' + type]) {
            return true;
        }

        obj['event_' + type] = fn;

        if (obj.addEventListener) {
            obj.addEventListener(type, obj['event_' + type], false);
        } else if (obj.attachEvent) {
            obj['event_' + type] = function() {return fn(jEvent.fixEvent())};
            obj.attachEvent('on' + type, obj['event_' + type]);
        } else {
            obj["on" + type] = obj['event_' + type];
        }
    },

    removeEvent: function(obj, type)
    {
        if (obj.removeEventListener) {
            obj.removeEventListener(type, obj['event_' + type], false);
        } else if (obj.detachEvent) {
            obj.detachEvent('on' + type, obj['event_' + type]);
        } else {
            obj["on" + type] = null;
        }

        obj['event_' + type] = null;
    },

    fixEvent: function(oEvent)
    {
        oEvent = oEvent || window.event;
        if (isIE && isWin) {
            oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
            oEvent.eventPhase = 2;
            oEvent.isChar = (oEvent.charCode > 0);

            var ep = eventPosition(oEvent);

            oEvent.pageX = oEvent.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);//ep.x;//
            oEvent.pageY = oEvent.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);//ep.y;//
            oEvent.preventDefault = function()
            {
                this.returnValue = false;
            }

            if (oEvent.type == "mouseout") {
                oEvent.relatedTarget = oEvent.toElement;
            } else if (oEvent.type == "mouseover") {
                oEvent.relatedTarget = oEvent.fromElement;
            }

            oEvent.stopPropagation = function()
            {
                this.cancelBubble = true;
            }

            oEvent.target = oEvent.srcElement;
            oEvent.time = (new Date).getTime();
        }
        return oEvent;
    }
};


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

String.prototype.ltrim = function(chars) {
    chars = chars || "\\s";
    return this.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

String.prototype.rtrim = function(chars) {
    chars = chars || "\\s";
    return this.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

String.prototype.trim = function(chars) {
    chars = chars || "\\s";
    return this.ltrim(chars).rtrim(chars);
}

//for popup
function getRealHeight()
{
    try {
        var $document_bottom = $(_('document-bottom'));
    } catch (e) {
        var $document_bottom = $('body').append('<div style="clear: both;"><!-- --></div><div id="document-bottom"><!-- --></div>').css('clear', 'both');
    }
    return Math.max(_('document-bottom').offsetTop, $(window).height());
}

var jGlassWindow = {
    showGlassWindow: function()
    {
        try {
            var $document_glass = $(_('document-glass'));
        } catch (e) {
            var $document_glass = $('<div id="document-glass"><!-- --></div>').prependTo('body');
        }

        var height = getRealHeight();
        $document_glass.css('height', height + 'px').show();
    },

    hideGlassWindow: function()
    {
        try {
            $(_('document-glass')).hide();
        } catch(e) {}
    }
};

var jTooltip = {
    showTooltip: function(text, x, y, id)
    {
        var id = id || '';
        try {
            var tooltip = jQuery(_('tooltip'));
        } catch (e) {
            var tooltip = jQuery('<div id="tooltip" class="tooltip"><p></p><span><!-- --></span></div>').prependTo('body');
        }
        tooltip.attr('title', id).find('p').html(text).end().show();
        y = y - 7; x = x - tooltip.get(0).offsetWidth - 8;
        tooltip.css({"top": y + "px", "left": x + "px", "z-index": "999"}).show();
    },

    hideTooltip: function(id)
    {
        try {
            var tooltip = jQuery(_('tooltip'));
            if (!id || tooltip.attr('title') == id) {
                tooltip.hide();
            }
        } catch(e) {}
    }
}

function Dispatcher()
{
    var _this = this;
    this.listeners = {};

    this.addListener = function(listener, events)
    {
        for (i = 0; i < events.length; i++) {
            if (!this.listeners[events[i]]) {
                this.listeners[events[i]] = [listener];
            } else if (!this.listeners[events[i]].inArray(listener)) {
                this.listeners[events[i]].push(listener);
            }
        }
    }

    this.removeListener = function(listener, events)
    {
        for (i = 0; i < events.length; i++) {
            if (this.listeners[events[i]]) {
                for (j = 0; j < this.listeners[events[i]].length; j++) {
                    if (this.listeners[events[i]][j] == listener) {
                        this.listeners[events[i]].splice(j, 1);
                    }
                }
            }
        }
    }

    var handlerEvent = function(e)
    {
        return _this.handle(e);
    }

    this.handle = function(e)
    {
        var rs = true;
        if (this.listeners[e.type]) {
            for (i = 0; i < this.listeners[e.type].length; i++) {
                this.listeners[e.type][i].listenerEvent(e);
            }
        }
    }

    this.showListeners = function()
    {
        var key;
        for (key in this.listeners)
          alert(key + '->' + this.listeners[key]);
    }

    jEvent.addEvent(document, 'click', handlerEvent);
    jEvent.addEvent(document, 'mouseup', handlerEvent);
    jEvent.addEvent(document, 'mousemove', handlerEvent);
    jEvent.addEvent(document.body, 'selectstart', handlerEvent);
}

jQuery(document).ready(
    function()
    {
        window.documentEventDispatcher = new Dispatcher;
        $("input.input_helper, textarea.input_helper").inputHelper();
        initQueryObjects();

    }
);

function objectPosition(obj)
{
     var oPosition = {x:0, y:0};
     if (obj == null) {
        return oPosition;
     }

     if (obj.offsetParent) {
        while (obj.offsetParent) {
            oPosition.x += obj.offsetLeft;
            oPosition.y += obj.offsetTop;
            obj = obj.offsetParent;
        }
     } else if (obj.x) {
        oPosition.x += obj.x;
        oPosition.y += obj.y;
     }

     return oPosition;
}

function checkFit(obj, str, innerobj) {
    var resolve = false;
    var innerobj = innerobj || false;

    if (!window.clones) {
        window.clones = {};
        window.clones_strings = {};
    }

    var clone = null;
    var clone_string = null;

    if (!window.clones[obj]) {
        clone = $(obj).clone().removeAttr('id')
                      .css({'width': 'auto',
                            'visibility': 'hidden',
                            'position': 'absolute',
                            'display': 'block',
                            'white-space': 'nowrap'});

        clone.insertBefore(obj);
        window.clones[obj] = clone.get(0);
        clone_string = window.clones_strings[obj] = (innerobj ? clone.find(innerobj).get(0) : clone.get(0));
    } else {
        clone = window.clones[obj];
        clone_string = window.clones_strings[obj];
    }

    clone_string.innerText ? clone_string.innerText = str : clone_string.textContent = str;
    return (clone.offsetWidth < obj.offsetWidth) ? true : false;
}


function dichotomyFit(obj, str, use_hellip, innerojb)
{
    var a = 0
    var b = str.length;

    while (b - a > 1) {
        var center = Math.ceil((a + b) / 2);
        var piece = str.substr(0, center);

        if (checkFit(obj, use_hellip ? piece + '…' : piece, innerojb)) {
            a = center;
        } else {
            b = center;
        }
    }
    return a;
}

function wordsFit(obj, str, innerojb) {
    var position = 0;
    var current_word = str;
    if (checkFit(obj, str, innerojb)) {
        position = str.length;
    } else {
        current_word = '';
        for (var i = 0; i < str.length; i++) {
            var chr = str.substr(i, 1);
            current_word = current_word + chr;
            if (i + 1 >= str.length || chr == ' ' && str.substr(i + 1, 1) != ' ' || chr != ' ' && str.substr(i + 1, 1) == ' ') {
                if (checkFit(obj, current_word, innerojb)) {
                    position = i;
                } else {
                    break;
                }
            }
        }
    }

    return position > 0 ? position : dichotomyFit(obj, current_word, innerojb);
}

function fitStringToObject(obj, str, lines, innerojb)
{
    if (str.length == 0) {
        return '';
    }

    var out = [];
    if (checkFit(obj, str, innerojb)) {
        out.push(str);
        return out;
    }

    for (var i = 0; i < lines; i++) {
        if (i < lines - 1) {
            position = wordsFit(obj, str, innerojb);
            out.push(str.substr(0, position));
            str = str.substr(position);
        } else {
            if (checkFit(obj, str, innerojb)) {
                out.push(str);
            } else {
                var a = dichotomyFit(obj, str, true, innerojb);
                out.push(str.substr(0, a) + '…');
            }
        }
    }

    return out;
}

function filenameFit(obj, str, lines, innerojb)
{
    if (str.length == 0) {
        return '';
    }

    var strings;
    var set_cache = false;
    var re = new RegExp('^window_desk_deskitem_[0-9]+_file_title$');
    if  (re.test(obj.id))
    {
    	var digit_regexp = /[0-9]/g;
		if (!window.string_cache)
		{
	        window.string_cache = {};
		}

		for (var i in window.string_cache)
		{
		    var n = i.length;
		    var test_string = str.substr(0, n);
		    if (test_string == i)
		    {
				strings = window.string_cache[i];
				break;
		    }

		    if (test_string.replace(digit_regexp, 0) == i.replace(digit_regexp, 0))
		    {
		    	var b = 0;
		    	strings = [];
		    	var j;
		    	for (j = 0; j < window.string_cache[i].length; j++)
		    	{
		    		var len = window.string_cache[i][j].length;
		    		strings.push(test_string.substr(b, len));
		    		b += len;
		    	}

		    	if (str.length > b)
		    	{
		    		strings[j-1] += '…';
		    	}

				break;
		    }
		}

		if (!strings)
		{
		    set_cache = true;
		}
    }


    if (!strings)
    {
		strings = fitStringToObject(obj, str, lines, innerojb);
        for (var i = 0; i < strings.length; i++) {
	    	strings[i] = htmlEscape(strings[i]);
        }
    }

    var out = strings.join('<br/>');

    var temp_string = strings.join('');
	var n = temp_string.length;

    if (set_cache && (strings.length > 1 || temp_string.substr(n-1) == '…'))
    {
		var has_dots = false;

		if (temp_string.substr(n-1) == '…')
		{
		    temp_string = temp_string.substr(0, n-1);
		    has_dots = true;
		}

		window.string_cache[temp_string] = strings;
    }


    if (strings.length > 1) {
        var hint = $('<a></a>').attr('title', str).addClass('hint_fit').css('color', $(obj).css('color'));
        out = hint.html(out);
    }

    delete(window.clones[obj]);
    delete(window.clones_strings[obj]);

    return out;
}



function sizeReadable(filestring)
{
    //'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'
    var map = {"B":"Б", "kB":"кБ", "MB":"МБ", "GB":"ГБ", "TB":"ТБ"}
    return map[filestring] ? map[filestring] : '-';
}

function htmlEscape(text)
{
//    return str.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&#39;');

    if (!window['__convert_to_text_div']) {
	window['__convert_to_text_div'] = document.createElement('div');
    }
    var div = window['__convert_to_text_div'];
    text = text || '';
    (typeof div.innerText != 'undefined') ? div.innerText = text : div.textContent = text;
    return div.innerHTML;
}

function Dump(o) {
    var rs = '';
    for (var i in o) {
        rs += i + "-> " + o[i] + "\n";
    }
    return rs;
}

jQuery.fn.inputHelper = function() {
    this.each(function(index) {
        var input = $(this);
        var properties = input.attr('title').split(':');

        input.val(properties[1]);
        input.attr('title', properties[1]);

        if (properties[0] == 'password') {
            var input2 = $(_(input.attr('id') + '_val'));

            input.focus(function()
                        {
                            input.hide();
                            input2.css('display', 'inline').focus();
                        });
            input2.blur(function ()
                        {
                            if (input2.val().length == 0) {
                                input2.hide();
                                input.css('display', 'inline');
                            }
                        });
        } else if (properties[0] == 'text') {
            input.focus(function()
                        {
                            if (input.val() == properties[1]) {
                                input.css('color', '#646464').val('');
                            }
                        })
                  .blur(function ()
                        {
                            if (input.val().length == 0) {
                                input.css('color', '#D8D8D8').val(properties[1]);
                            } else {
                                input.css('color', '#646464');
                            }
                        });
        } else if (properties[0] == 'text2') {
            input.focus(function() {
                            if (input.val() == properties[1]) {
                                input.css('color', '#646464').val(properties[2].replace('..', ':'));
                            }
                        })
                  .blur(function () {
                            if (input.val().length == 0 || input.val() == properties[2].replace('..', ':')) {
                                input.css('color', '#D8D8D8').val(properties[1]);
                            } else {
                                input.css('color', '#646464');
                            }
                        });
        }
    });
}

jQuery.fn.inputHelperClear = function() {
    this.each(function(index) {

        var input = $(this);

        var title = input.attr('title');
        if (input.val() == title) {
            input.val('');
        }
    });
}

jQuery.fn.inputHelperRealVal = function() {

    var input = $(this);

    var title = input.attr('title');
    if (input.val() == title) {
        return '';
    }
    return input.val();
}
