var relativepath = '';
var rdpopup = null;
var dict = {};
var vars = { lng: 'ru', pagename: '', daysL: 'days', nightsL: 'nights' };
var mlDict = {};
var monthsShort = [];
var _dSeconds = 86400000;

Date.prototype.increment = function (d, m, y) {
    if (typeof (d) != 'undefined') {
        return (new Date(this.getTime() + (d * _dSeconds)));
    }
};
Date.prototype.diff = function (d) {
    return Math.floor((this - d) / _dSeconds);
};
Date.prototype.jsonString = function () {
    return this.getFullYear() + '-' + (this.getMonth() + 1) + '-' + this.getDate();
};
Date.prototype.verbalString = function () {
    return this.getDate() + ' ' + monthsShort[this.getMonth()] + ' ' + this.getFullYear().toString().substr(2, 2);
};
String.prototype.nl = function () {
    /*prototype of all strings extended with function to insert br's*/
    return this.replace(/\n/g, "<br />");
};
String.prototype.getInt = function () {
    var retval = parseInt(this);
    return isNaN(retval) ? 0 : retval;
};
String.prototype.isEmpty = function () {
    return (this == null || this == '' || this.replace(/\s+/g, '') == '');
};
var tw_commons = {
    sToDate: function (ds) {
        var a = new Date();
        var aArr = ds.split('-');
        a.setFullYear(aArr[0], aArr[1] - 1, aArr[2]);
        return a;
    },
    getTop: function (oElement, offset) {
        var iResult = oElement.offsetTop;
        while (oElement.offsetParent) {
            oElement = oElement.offsetParent;
            iResult += oElement.offsetTop;
        }
        return typeof (offset) == 'undefined' ? iResult : iResult + offset;
    },
    getLeft: function (oElement, offset) {
        var iResult = oElement.offsetLeft;
        while (oElement.offsetParent) {
            oElement = oElement.offsetParent;
            iResult += oElement.offsetLeft;
        }
        return typeof (offset) == 'undefined' ? iResult : iResult + offset;
    },
    getScrollTop: function (offset) {
        return (window.scrollY || document.body.parentNode.scrollTop) + offset;
    },
    getScrollLeft: function (offset) {
        return (window.scrollX || document.body.parentNode.scrollLeft) + offset;
    },
    mOverDP: function () {
        $(this).css({ 'bottom': '0px', 'right': '0px' });
    },
    mOutDP: function () {
        $(this).css({ 'bottom': '1px', 'right': '1px' });
    }
};
function twRdPopUp() {
    if (!this.twRdPopUp_) {
        var xxx = function () { };
        xxx.prototype = {
            PH: {},
            PHC: null,
            subscribers: {},
            position: function (css) {
                twRdPopUp().PH.css(css);
            },
            init: function (onHides, ph) {
                if (ph) {
                    twRdPopUp().PH = $(ph);
                }
                $.extend(twRdPopUp().subscribers, onHides);
            },
            render: function () {
                var _rp = twRdPopUp();
                _rp.PHC = $('#popup_content', _rp.PH);
                $('.crossClose', _rp.PH).html('<span class="fl ml13">' + dict.LBL_CLOSE + '</span>').wrap('<div class="crossCloseShad fr"></div>')
                .bind('mouseover', tw_commons.mOverDP).bind('mouseout', tw_commons.mOutDP)
                .bind('click', _rp.hide)
                .attr('title', dict.LBL_HIDE_DETAILS);
                return _rp;
            },
            attach: function (content) {
                twRdPopUp().PHC.append(content);
                return twRdPopUp();
            },
            hide: function () {
                twRdPopUp().PH.hide();
                for (var key in twRdPopUp().subscribers) {
                    var s = twRdPopUp().subscribers[key];
                    if (typeof (s) == 'function') s.call(this);
                }
            },
            show: function (f, data, onShown) {
                var _callee = this;
                var _rp = twRdPopUp();
                if (!(_rp.PHC)) {
                    var _callee = this;
                    _rp.PH.load(relativepath + 'Controls/rdpopup.htm', function () {
                        _rp.render();
                        _rp.show.call(_callee, f, data, onShown);
                    });
                    return;
                }
                _rp.hide();
                if (typeof (f) == 'function') f.call(this, data);
                _rp.PH.show();
                if (typeof (onShown) == 'function') onShown.call(this, data);
                return _rp;
            }
        };
        this.twRdPopUp_ = new xxx();
    }
    return this.twRdPopUp_;
};
function twState() {
    if (!this.twState_) {
        function xxx() { };
        xxx.prototype = {
            opts: {
                ss: 'searchScope',
                favs: 'userFavorites',
                UILang: 'UILang',
                UISkin: 'UISkin'
            },
            save: function(){},
            setVal: function (key, data, p) {
                var params = [key, (typeof (data) == 'object' ? $.toJSON(data) : data)];
                if (p) params.push({ hoursToLive: 24 * p });
                jaaulde.utils.cookies.set.apply(this, params);
            },
            getValS: function (key) {
                return jaaulde.utils.cookies.get(key);
            },
            getVal: function (key) {
                return $.evalJSON(this.getValS(key));
            },
            setLang: function (lang) {
                this.setVal(this.opts.UILang, lang, 30);
            },
            getLang: function () {
                return this.getValS(this.opts.UILang);
            },
            getSkin: function () {
                return this.getValS(this.opts.UISkin);
            },
            setSearchScope: function (data) {
                this.setVal(this.opts.ss, data,1);
            },
            getSearchScope: function () {
                return this.getVal(this.opts.ss);
            },
            setFavs: function (data) {
                this.setVal(this.opts.favs, data, 30);
            },
            getFavs: function () {
                return this.getVal(this.opts.favs);
            },
            extend: function (p) {
                $.extend(this, p || {});
            }
        };
        this.twState_ = new xxx();
    };
    return this.twState_;
};
function twUrl() {
    if (!this.twUrl_) {
        var p = { url: window.location.href,
            hasParams: window.location.href.indexOf('?') > 0
        };
        function xxx() { };
        xxx.prototype = {
            hasParams: p.hasParams,
            checkHasParams: function (url) { return url.indexOf('?') >= 0; },
            url: p.url,
            clearParams: function () {
                this.hasParams = false;
                return this.url.substr(0, this.url.indexOf('?'));
            },
            removeParam: function (pname) {
                if (!this.hasParams) return this.url;

                var retval = '';
                for (var i = 0, j = 0, pp = this.url.split('?')[1].split('&'), _p; _p = pp[i]; i++) {
                    _p = _p.split('=');
                    if (_p[0] != pname) {
                        j++;
                        retval += (j == 1 ? '?' : '&') + _p[0] + '=' + _p[1];
                    }
                }
                retval = this.clearParams() + retval;
                this.hasParams = this.checkHasParams(retval);
                return retval;
            },
            setUrl: function (url) {
                this.url = url;
                this.hasParams = this.checkHasParams(url);
            },
            setParam: function (pname, pvalue) {
                var url = this.removeParam(pname);
                this.url = url + (this.checkHasParams(url) ? '&' : '?') + pname + '=' + pvalue
                return this.url;
            },
            logon: function (cburl) {
                if (typeof (cburl) == 'undefined' || cburl == '') {
                    window.location = this.removeParam('login');
                }
                else {
                    window.location = this.clearParams() + "?navurl=" + cburl;
                }
            }
        };
        this.twUrl_ = new xxx();
    }
    return this.twUrl_;
};
/*****************************************
* veil from www.wingo.com/jt_/index.html *
******************************************/
function jt_AddListener(obj, evType, fn) {
    if (obj.addEventListener) { obj.addEventListener(evType, fn, false); }
    else if (obj.attachEvent) { obj.attachEvent('on' + evType, fn); }
}
function jt_RemListener(obj, evType, fn) {
    if (obj.removeEventListener) { obj.removeEventListener(evType, fn, false); }
    else if (obj.detachEvent) { obj.detachEvent('on' + evType, fn); }
}
function jt_winW() {
    if (document.documentElement && (document.documentElement.clientWidth > 0)) { return document.documentElement.clientWidth; }
    else if (window.innerWidth) { return window.innerWidth; }
    else { return document.body.clientWidth; }
}

function jt_winH() {
    if (window.innerHeight) { return window.innerHeight; }
    else if (document.documentElement && (document.documentElement.clientHeight > 0)) { return document.documentElement.clientHeight; }
    else { return document.body.clientHeight; }
}
function jt_valPx(pixels) {
    return isNaN(pixels) ? 0 : pixels + "px";
}
var jt_BodyZ = { /***** manages z-Index visibility */
    toTop: function (elm) { // adds any 'elm' to top of 'jt_BodyZ.que'
        if (!jt_BodyZ.que) {
            jt_BodyZ.que = document.createElement("div");
            document.body.appendChild(jt_BodyZ.que);
        }
        if (!elm.jt_BodyZZ) {
            elm.jt_BodyZZ = jt_BodyZ.nid++;
            jt_AddListener(elm, "mousedown", function () {
                jt_BodyZ.toTop(elm);
            });
            jt_BodyZ.que.appendChild(elm);
            jt_BodyZ.set(elm);
        }
        else if (elm.jt_BodyZZ != jt_BodyZ.last.jt_BodyZZ) jt_BodyZ.set(elm);
    },

    // PRIVATE BELOW
    set: function (elm) {
        elm.style.zIndex = jt_BodyZ.nextZ++;
        jt_BodyZ.last = elm;
    },
    nid: 1,
    nextZ: 1
};

var jt_Veil = { /***** cooperates w/ 'jt_BodyZ', required by 'jt_DialogBox' */
    show: function (showIt) {
        jt_Veil.init();
        if (!showIt) jt_Veil.reqs.pop();
        else if (jt_BodyZ.last) jt_Veil.reqs.push(jt_BodyZ.last);
        if (jt_Veil.reqs.length > 0) {
            jt_Veil.fix();
            jt_Veil.veil.style.zIndex = jt_Veil.reqs[jt_Veil.reqs.length - 1].style.zIndex - 1;
            jt_BodyZ.que.insertBefore(jt_Veil.veil, jt_Veil.reqs[jt_Veil.reqs.length - 1]);
        }
        jt_Veil.veil.style.display = (jt_Veil.reqs.length == 0) ? "none" : "block";
    },

    // PRIVATE BELOW
    fix: function () {
        jt_Veil.veil.style.width = jt_valPx(Math.max(document.body.scrollWidth, jt_winW()));
        jt_Veil.veil.style.height = jt_valPx(Math.max(document.body.scrollHeight, jt_winH()));
    },
    init: function () {
        if (typeof jt_Veil.veil == "undefined") { // once per page
            jt_Veil.reqs = [];
            jt_Veil.veil = document.createElement('div');
            for (var prop in jt_Veil.css) jt_Veil.veil.style[prop] = jt_Veil.css[prop];
            jt_Veil.veil.innerHTML = " ";
            if (jt_BodyZ.que) jt_BodyZ.que.insertBefore(jt_Veil.veil, jt_BodyZ.que.firstChild);
            else jt_BodyZ.toTop(jt_Veil.veil);
            jt_AddListener(window, "resize", jt_Veil.fix);
        }
    },
    css: { position: "absolute", display: "none", top: 0, left: 0, cursor: "not-allowed", backgroundColor: "#000000", filter: "alpha(opacity=20)", opacity: 0.2 }
};
function twAjaxMonitor() {
    if (!this.twAjaxMonitor_) {
        function xxx() { };
        var jsLog = (typeof (jsLog) == 'function' ? jsLog : function (msg, color) { });
        jsLog('twAjaxMonitor.constructor');
        xxx.prototype = {
            opts: {
                PH: $('#dataExchange'),
                REQ: $('#loadingRequest')
            },
            ajaxCount: 0,
            queue1: [],
            queue2: [],
            initQueues: function () {
                jsLog('initQueues', 'red');
                twAjaxMonitor().queue1 = [];
                twAjaxMonitor().queue2 = [];
            },
            enqueue: function (todo) {
                twAjaxMonitor().queue1.push({ cbId: twAjaxMonitor().queue1.length, todo: todo });
                jsLog('enqueue:Q1:' + twAjaxMonitor().queue1.length);
                return twAjaxMonitor().queue1.length - 1;
            },
            dequeue: function (cbId, retval) {
                var qi = $.grep(twAjaxMonitor().queue1, function (item) { return item.cbId == cbId; });
                if (qi[0]) twAjaxMonitor().queue2.push({ cbId: cbId, todo: qi[0].todo, retval: retval });
                jsLog('dequeue:QQ:' + twAjaxMonitor().queue1.length + '/' + twAjaxMonitor().queue2.length
                     + ', cbId:' + cbId + ', qi[0]:' + qi[0] + ', retval:' + retval);
                if (twAjaxMonitor().queue2.length == twAjaxMonitor().queue1.length) {
                    var q = twAjaxMonitor().queue2;
                    twAjaxMonitor().initQueues();
                    for (var i = 0; i < q.length; i++) {
                        var qi = $.grep(q, function (_qi) { return _qi.cbId == i; })[0];
                        jsLog('todo.call:' + i, 'white');
                        qi.todo.call(this, i, qi.retval);
                    }
                }
            },
            processAsTransaction: function (flist) {
                while (flist.length > 0) flist.shift().call(this);
            },
            drawProgress: function (incr) {
                this.ajaxCount += incr;
                var width = 16 * this.ajaxCount;
                this.opts.REQ.css({ 'width': width });
            },
            serverReqStart: function () {
                jsLog('serverReqStart', 'green');
                var l = twAjaxMonitor();
                var top = tw_commons.getScrollTop(0);
                var left = ($('body').width() + tw_commons.getLeft($('body')[0])) / 2 - l.opts.PH.width() / 2;
                l.opts.PH
                            .css('background-color', 'yellow')
                            .css({ 'top': top + 'px', 'left': left + 'px' })
                            .fadeIn('fast');
                jt_BodyZ.toTop(l.opts.PH[0]);
                jt_Veil.show(true);
            },
            serverReqStop: function () {
                twAjaxMonitor().opts.PH.fadeOut('slow');
                jt_Veil.show(false);
            },
            serverOpAdd: function (event) {
                jsLog('serverOpAdd:url:' + arguments[2].url.match(/(.[^\?]*)(\?.*)?/)[1], 'orange');
                twAjaxMonitor().drawProgress(+1);
            },
            serverOpRemove: function () {
                jsLog('serverOpRemove:url:' + arguments[2].url.match(/(.[^\?]*)(\?.*)?/)[1], 'orange');
                twAjaxMonitor().drawProgress(-1);
            },
            serverOpError: function (event, XMLHttpRequest, ajaxOptions, thrownError) {
                jsLog('serverOpError:url:' + arguments[2].url.match(/(.[^\?]*)(\?.*)?/)[1], 'cyan');
                twAjaxMonitor().initQueues();
                twAjaxMonitor().opts.PH.css('background-color', 'red');
            }
        };
        this.twAjaxMonitor_ = new xxx();
        if (typeof(twScrollDispatcher) != 'undefined') twScrollDispatcher().subscribers.dataExchange = { obj: twAjaxMonitor().opts.PH };
        twAjaxMonitor().opts.PH.hide();
    }
    return this.twAjaxMonitor_;
};
function twScrollDispatcher() {
    if (!this.twScrollDispatcher_) {
        function dispatcher() {
        };
        dispatcher.prototype = {
            active: false,
            sPosition: 0,
            subscribers: {},
            startAnimation: function () {
                var sb = twScrollDispatcher().subscribers;
                for (var key in sb) {
                    if (sb[key]) {
                        var subscriber = sb[key];
                        if (subscriber.gizmo) {
                            /* scroll between topmost and bottommost y */
                            var _t = tw_commons.getTop(subscriber.gizmo);
                            var _h = subscriber.gizmo.clientHeight;
                            var _oh = subscriber.obj[0].clientHeight;
                            var bottommost = _t + _h - _oh ;
                            if (_t < this.sPosition && this.sPosition < bottommost) subscriber.obj.animate({ 'top': this.sPosition + 'px' }, 'fast');
                            else if (this.sPosition < _t) subscriber.obj.css({ 'top': _t + 'px' }, 'fast');
                            else if (this.sPosition > bottommost) subscriber.obj.css({ 'top': bottommost + 'px' }, 'fast');

                        }
                        else if (subscriber.start) {
                            subscriber.obj.animate({ 'top': (this.sPosition + (subscriber.start || 0)) + 'px' }, 'fast');
                        }
                    }
                }
            },
            checkReposition: function () {
                y = tw_commons.getScrollTop(0);
                if (this.sPosition == y) {
                    this.active = false;
                    this.startAnimation()
                } else if (!this.active) {
                    this.sPosition = y;
                    setTimeout(function () { twScrollDispatcher().checkReposition(100); }, 250);
                    this.active = true;
                } else {
                    this.sPosition = y;
                }
            }
        };
        this.twScrollDispatcher_ = new dispatcher();
    }
    return this.twScrollDispatcher_;
};
/* twInplaceEditable
*/
(function ($) {
    $.fn.twInplaceEditable = function (params) {
        inplaceEditable(this, params);
        return this;
    };
    inplaceEditable = function (el, params) {
        var opts = { color: 'red',
            evtIn: 'focus',
            evtOut: 'blur'
        };
        $.extend(opts, params);
        $(el)
                                .attr('contentEditable', 'true')
                                .unbind(opts.evtIn).bind(opts.evtIn, function () {
                                    $(this).attr('oldVal', $(this).html());
                                });
        if (opts.evtOut) {
            $(el).unbind(opts.evtOut).bind(opts.evtOut, function () {
                if ($(this).attr('oldVal') != $(this).html()) {
                    $(this).attr('changed', '1').css('color', opts.color);
                }
            });
        }
    };
})(jQuery);
/* tweedExpander
*/
(function ($) {
    twExpander = function (el, params) {
        var tgt = $(el);
        var opts = {
            collapsedCSS: 'ui-icon-triangle-1-e',
            expandedCSS: 'ui-icon-triangle-1-s',
            expanded: 'expanded',
            marker: 'expander',
            onClick: null, /*must have onSuccess callback parameter*/
            toggleDetails: function () {
                if (typeof (opts.onClick) == 'function') return opts.onClick.call(tgt, opts.onSuccess);
                opts.onSuccess.call(tgt);

            },
            onSuccess: function () {
                var tf = tgt.prev().hasClass(opts.collapsedCSS);
                if (opts.selector) $(opts.selector).toggle(tf);
                tgt.prev().toggleClass(opts.collapsedCSS).toggleClass(opts.expandedCSS);
                tgt.removeAttr(opts.expanded);
                if (tgt.prev().hasClass(opts.expandedCSS)) tgt.attr(opts.expanded, opts.expanded);
            }
        };

        var methods = {
            expanded: function (tf) {
                if (tgt.prev().attr('name') != opts.marker) tgt = $('[name="' + opts.marker + '"]', tgt).next();
                if (typeof (tf) == 'undefined') return tgt.prev().hasClass(opts.expandedCSS);
                tgt.removeAttr(opts.expanded);
                if (!tf) tgt.attr(opts.expanded, opts.expanded);
                tgt.prev().toggleClass(opts.expandedCSS, !tf);
                tgt.prev().toggleClass(opts.collapsedCSS, tf);
                opts.toggleDetails();
                /*
                if ((tf && !tgt.prev().hasClass(opts.expandedCSS))
                || (!tf && tgt.prev().hasClass(opts.expandedCSS))) {
                tgt.trigger('click');
                }
                */
            },
            remove: function () {
                tgt.unbind('click')
                    .removeClass(opts.collapsedCSS)
                    .removeClass(opts.expandedCSS)
                    .removeClass('ptr')
                    .removeAttr(opts.expanded)
                    .prev('[name="' + opts.marker + '"]').remove();
            },
            obj: tgt
        };
        var initialized = (tgt.prev().attr('name') == opts.marker);
        if (!params) return methods;

        if (typeof (params) == 'string' && params != 'next') {
            opts.selector = $(params);
        }
        else if (typeof (params) == 'object') {
            $.extend(opts, params);
        }
        else opts.selector = (initialized?tgt.closest('fieldset'):tgt).next();

        if (initialized) return methods;

        tgt.toggleClass('ptr', true).unbind('click')
            .bind('click', opts.toggleDetails)
            .wrap($('<fieldset class="fsPlain"></fieldset>'))
            .before($('<div class="ui-icon fl" name="expander"></div>').toggleClass(opts.collapsedCSS));

        return methods;
    };
    $.fn.twExpander = function (params) {
        return twExpander(this, params);
    };
})(jQuery);
/* clickable case
*/
(function ($) {
    twTouchCase = function (el, params, OnOff) {
        if ($(el).length > 1) {
            $(el).each(function (i, item) { $(item).twTouchCase(params, OnOff); });
            return el;
        }
        var opts = {
            togglable: false,
            shadClassName: 'cbShad',
            iconClassName: 'twTouchCB',
            toggle: function () {
                var tgt = $(this);
                var shed = tgt.closest('.cbShad');
                var shedImgSrc = relativepath + 'images/design/images/cbactive.gif';
                if (!tgt.attr('checked')) {
                    tgt.unbind('mouseout');
                    tgt.append($('<img src="' + shedImgSrc + '"></img>'));
                    tgt.attr('checked', true);
                    tw_commons.mOverDP.call(tgt);
                }
                else {
                    tgt.removeAttr('checked');
                    tgt.children().remove('img');
                    tgt.bind('mouseout', tw_commons.mOutDP);
                    tw_commons.mOutDP.call(tgt);
                }
            }
        };
        var f = {
            mOver: function () { tw_commons.mOverDP.call(el); },
            mOut: function () { tw_commons.mOutDP.call(el); },
            wrap: function (tgt) {
                $(tgt).wrap('<div class="' + opts.shadClassName + '"></div>')
                    .toggleClass(opts.iconClassName, true)
                    .bind('mouseover', this.mOver).bind('mouseout', this.mOut);
                if (opts.togglable) { $(tgt).bind('click', opts.toggle); }
                if (typeof (opts.onClick) == 'function') { $(tgt).bind('click', opts.onClick); }
            }
        };
        $.extend(opts, params || {});
        if (typeof (OnOff) != 'undefined') {
            if (OnOff) {
                $(el).removeAttr('checked');
            }
            else {
                $(el).attr('checked', 'true');
            }
            opts.toggle.call(el);
            return el;
        }
        f.wrap(el);
        return el;
    };
    $.fn.twTouchCase = function (params, OnOff) {
        return twTouchCase(this, params, OnOff);
    };
})(jQuery);
function twStore(handler, contextSetter) {
    var obj = this;
    obj.cache = {};
    obj.reset = function () {
        obj.cache = {};
        return obj;
    };
    obj.getData = function (id, callback, onSuccess, data) {
        if (typeof (callback) == 'undefined') return obj.cache[id] ? (obj.cache[id].data || obj.cache[id]) : null; /*sync call from cache*/
        if (typeof (callback) == 'function' && obj.cache[id]) { /*async call*/
            callback.call(this, obj.cache[id].data || obj.cache[id], obj.cache[id].flags);
            if (typeof (onSuccess) == 'function') onSuccess.call(this);
            return;
        }
        obj.requestData.call(this, id, callback, onSuccess, data);
    };
    obj.requestData = function (id, callback, onSuccess, data) {
        var origin = this;
        var rp = { id: id };
        var _data =
              (typeof (data) == 'undefined') ? { id: rp.id, data: $.toJSON(contextSetter.call(this)) }
            : (typeof (data) == 'object') ? { data: $.toJSON(data) }
            : (typeof (data) == 'string') ? { data: data }
            : { data: '{}' };
        var _params;
        var _cbCurrent = function (_cbId, retval) {
            if (!obj.processResponce(rp, retval)) return;
            obj.getData.call(origin, rp.id, callback, onSuccess);
        };
        if (typeof (twAjaxMonitor) != 'undefined') {
            var _cbId = twAjaxMonitor().enqueue(_cbCurrent);
            _params = [handler, $.extend(_data, { queryTime: new Date() }),
            function (retval) { twAjaxMonitor().dequeue(_cbId, retval); }, "json"];
        }
        _params = [handler, $.extend(_data, { queryTime: new Date() }),
            function (retval) { _cbCurrent(null, retval); }, "json"];

        if (data) $.post.apply(this, _params);
        else $.get.apply(this, _params);
    };
    obj.processResponce = function (rp, retval) {
        if (retval.error) { alert(retval.error + '\r\n' + (retval.extext ? retval.extext : '')); return false; }
        rp.id = retval.id || rp.id;
        obj.cache[rp.id] = { data: retval.data, flags: retval.flags };
        return true;
    };
};
/* twDatePicker relies on jquery.calendar-widget.js
*/
(function ($) {
    $.fn.twDatePicker = function (params) {
        twDatePicker(this, params);
        return this;
    };
    twDatePicker = function (el, params) {
        var opts = {
            month: (new Date()).getMonth(),
            year: (new Date()).getFullYear(),
            showNav: 'both',
            onDayClick: true,
            evt: 'focus',
            bindedTo: el,
            displayTo: null,
            self: el
        };
        var dpFunctions = {
            buildinOnClick: function (dString) { /* buildin function */
                if (!opts.displayTo) return;
                opts.displayTo.html(tw_commons.sToDate(dString).verbalString());
            },
            render: function (tgt) {
                var datePicker = $('<div class="date-picker"></div>');
                $('body').append(datePicker);
                if (typeof (opts.bindedTo) == 'string' && el[opts.bindedTo]) { opts.bindedTo = el[opts.bindedTo].call(el); }
                if (typeof (opts.displayTo) == 'string' && el[opts.displayTo]) opts.displayTo = el[opts.displayTo].call(el);
                if (typeof (opts.onDayClick) != 'function') {
                    opts.onDayClick = dpFunctions.buildinOnClick;
                }
                /*else {
                    dpFunctions.userOnClick = opts.onDayClick;
                    opts.onDayClick = function (dString) {
                        if (dpFunctions.userOnClick.call(el, dString)) {
                            dpFunctions.buildinOnClick.call(el, dString);
                        }
                    };
                }*/
                var dstring = ((opts.bindedTo.val() || '').isEmpty() ? (opts.bindedTo.text() || '') : opts.bindedTo.val()).split('-');

                opts.month = parseInt(dstring[1]) - 1;
                opts.year = parseInt(dstring[0]);
                opts.day = parseInt(dstring[2]);
                opts.dateToHighlite = new Date(opts.year, opts.month, opts.day);

                datePicker.calendarWidget(opts);

                var cw = tgt.clientWidth;
                var ch = tgt.clientHeight;
                var valLeft = tw_commons.getLeft(tgt, cw == 0 ? 0 : cw - datePicker.width());
                var valTop = tw_commons.getTop(tgt, ch == 0 ? 20 : ch);
                datePicker.css('display', 'block').css('left', valLeft + 'px').css('top', valTop + 'px');
                datePicker.focus();
            }
        };
        $.extend(opts, params);
        el.unbind(opts.evt).unbind('mouseover').unbind('mouseout')
            .bind('mouseover', tw_commons.mOverDP).bind('mouseout', tw_commons.mOutDP).bind(opts.evt, function (event) {
                event.stopPropagation();

                if ($('.date-picker').length > 0) {
                    $('.date-picker').remove();
                } else {
                    setTimeout(function () { dpFunctions.render(event.currentTarget); }, 5);
                }

                $('body').unbind('click').bind('click', function (event) {
                    //event.stopPropagation();
                    if ($('.date-picker').length > 0 && event.target != opts.displayTo[0] && event.target.name != 'prevMonth' && event.target.name != 'nextMonth') {
                        $('.date-picker').remove();
                    }
                });
            });
    };
})(jQuery);
