/**** /js/moikrug/ui/Tooltip.js ****/
Lang.module('moikrug.ui.Tooltip');
   
moikrug.ui.Tooltip = Lang.createClass(Widget, {
    init: function(node, options) {
        this.baseConstructor(node);
        this.ttl = options.ttl || 0;
        this.tellServer = options.tellServer || null;
        this.options = options;
        
        this.parse();
        this.bindEvents();
        this.restore();
       
        Postprocess.cleanNode(this.controlClose);
    },

    parse: function() {
        this.controlClose = this.node.down(this.options.controlCloseSelector || '.x_close');
    },

    bindEvents: function() {
        if(this.controlClose) {
            Event.observe(this.controlClose, 'click', this.onControlCloseClick.bindAsEventListener(this));
        }
        
        this.node.observe('tooltip:close:' + this.node.id, this.close.bind(this));
    },

    onControlCloseClick: function(event) {
        this.close();
        Event.stop(event);
        return false;
    },
    
    maybeTellServer: function() {
        if (this.tellServer) {
        	JsHttpRequest.query(this.tellServer);
            //new Ajax.Request(this.tellServer, {method: "GET"});
        }
    },

    close: function() {
        this.node.addClassName('hidden');
        var date = new Date();
        date.setTime(date.getTime()+(this.ttl * 24 * 60 * 60 * 1000 ));
        Cookie.set('[uid]_Tooltip#' + this.node.id, '1', this.ttl ? date : null);
        this.maybeTellServer();
    },

    restore: function() {
        var tmp = Cookie.get('[uid]_Tooltip#' + this.node.id);
        if(tmp) {
        	this.node.addClassName('hidden');
        }
    }

});

moikrug.ui.Tooltip.getInstance = function(node, options) {
     return Widget.getInstance(node) || Widget.registerInstance(node, new moikrug.ui.Tooltip(node, options));
};
;

/**** /js/moikrug/ui/Suggest.js ****/
Lang.module("moikrug.ui.Suggest");

Lang.include("moikrug.widget.Clonable");

moikrug.ui.Suggest = Lang.createClass(moikrug.widget.Clonable, {

/**
 * @author akoval
 * 
 * Options:
 *    invitation:                  text in suggest when there's no user input
 *    requestParams:               additional params for ajax request
 *    serverTarget:                url part after /widgets/ajax/
 *    selectedClassName:           css class name for selected item
 *    hoverClassName:              css class name for hover interaction
 *    additionalListClassName:     optional css class name for the list of suggestons
 *    updateInputOnLoopingThru:    flag indicating if input field value should be replaced or not
 *                                 with value of current(highlighted) one during looping
 *                                 through the list of suggestions
 *    showInvitationOnBlur:        flag indicating if invitation container can be displayed after occuring onBlur event on input field
 *    showInvitation:              flag indicating if invitation container should be displayed
 *    showLoadingIndicator:        flag indicating if loading indicator should be displayed
 *
 * @param options see options description
 */
    init: function(node, options, name, className) {
        this.baseConstructor(node, options, name, className || '');
        if (!options.invitation && window.DIC) {
            Object.extend({
                invitation: DIC.dropdown_invitation
            }, this.options);
        }
        if (this.options.requestParams) {
            this.requestParams = this.options.requestParams;
        }
        this.preSelectedElementIndex = null;
        this.defaults = {
            selectedClassName:           "selected",
            hoverClassName:              "hover",
            additionalListClassName:     "",
            updateInputOnLoopingThru:    true,
            showInvitationOnBlur:        false,
            showInvitation:              true,
            showLoadingIndicator:        true
        };
        
        this.overrideOptions();
        
        this.list = this.createList();
        this.listAttached = false;

        this.indicator = this.createIndicator();
        this.indicatorAttached = false;
        
        this.invitation = this.options.invitation;
        this.node.setAttribute("autocomplete", "off");
        this.form = this.node.form;
    },

    _createClonedWidget: function(node, options, name, className) {
        return new moikrug.ui.Suggest(node, options, name, className).bindEvents();
    },
    
    overrideOptions: function() {
        for(var i in this.defaults) {
            if(!this.options.hasOwnProperty(i)) {
                this.options[i] = this.defaults[i];
            }
        }
    },

/**
 * Creates a <ul> list that will contain suggest items
 */
    createList: function() {
        var list = document.createElement("ul");
        list.className = "newDropDownList suggest-list " + this.options.additionalListClassName;
        list.style.display = "none";
        return list;
    },

/**
 * Attaches list to DOM. Should be called after <tt>onload</tt>
 * due to problems in IE
 */
    attachList: function() {
        this.listAttached = true;
        var div = document.createElement("div");
        div.className = "form";
        div.appendChild(this.list);
        document.body.appendChild(div);
    },

/**
 * Updates width of the list so that it's the same as of input
 */
    updateListWidth: function() {
        if (this.node.offsetWidth) {
            var newWidth = this.node.offsetWidth - 2;
            newWidth = Math.max(this.options.minWidth || 0, newWidth);
            this.list.style.width = newWidth + 'px';
        }
    },

/**
 * Updates position of the list, so that it's just below the input
 * Currently the position is bottom-input-border to top-list-border
 */
    updateListPosition: function() {
        var offset = $(this.node.parentNode).cumulativeOffset();
        this.list.style.left = offset[0] + "px";
        this.list.style.top = offset[1] + this.node.offsetHeight + "px";
    },

    updateListAppearance: function() {
        this.updateListWidth();
        this.updateListPosition();
    },

    showList: function() {
        if (!this.listAttached) {
            this.attachList();
        }
        if (this.list.firstChild) {
            this.preSelectedElementIndex = null;
            this.updateListAppearance();
            this.list.style.display = "block";
        }
        if (window.WCH) {
            window.WCH.Apply(this.list, this.list.parentNode, true);
        }
    },

    hideList: function() {
        this.clearList();
        this.list.style.display = "none";
        if (window.WCH) {
            window.WCH.Discard(this.list, this.list.parentNode, true);
        }
    },

/**
 * Creates an indicator to show that AJAX request is sent
 */
    createIndicator: function() {
        var indicator = document.createElement("img");
        indicator.style.position = "absolute";
        indicator.src = "/images/icon_updating.gif";
        return indicator;
    },

/**
 * Attaches indicator to DOM. Should be called after <tt>onload</tt>
 * due to problems in IE
 */
    attachIndicator: function() {
        this.indicatorAttached = true;
        document.body.appendChild(this.indicator);
    },

    updateIndicatorPosition: function() {
        var offset = Position.cumulativeOffset(this.options.updateIconOffsetNode || this.node.parentNode);
        var leftOffset = 0;
        if (this.options.rightIndicator) {
            leftOffset = 5 + this.node.getWidth();
        } else {
            leftOffset = -24;
        }
        this.indicator.style.left = offset[0] + leftOffset + 'px';
        this.indicator.style.top = offset[1] + 5 + 'px';
        this.indicator.style.zIndex = 100;
    },
    
    /**
     * Displays loading indicator
     * 
     * In the case showInvitation flag is set to FALSE
     * we have an opportunity to show invitation on demand
     * by passing optional parameter
     * 
     * @param {Boolean} showOnDemand
     */
    showIndicator: function(showOnDemand) {
        if (this.options.showLoadingIndicator || !!showOnDemand) {
               if (!this.indicatorAttached) {
                this.attachIndicator();
            }
            this.updateIndicatorPosition();
            this.indicator.style.visibility = "visible";
        }
    },

    hideIndicator: function() {
        this.indicator.style.visibility = "hidden";
    },
    
    _getServerUrl: function() {
        if (/^\w+$/.test(this.options.serverTarget)) {
            return window.location.protocol + '//' + window.location.host + '/widgets/ajax/' + this.options.serverTarget;
        } else {
            return this.options.serverTarget;
        }
    },

    requestList: function() {
        if (this.node.value.length === 0) {
            this.hideList();
            this.hideIndicator();
            this.showInvitation();
            JsHttpRequest.clearTimeout(this.timeout);
            return;
        }
        this.oldReqValue = this.node.value;
        this.JsHttpRequest = new JsHttpRequest();
        this.JsHttpRequest.onreadystatechange = (function() {
            if (this.JsHttpRequest.readyState != 4) {
                return;
            }
            this.hideList();
            this.fillList(this.JsHttpRequest.responseJS.result);
            this.showList();
            this.hideIndicator();
        }).bind(this);
        this.JsHttpRequest.caching = true;
        this.JsHttpRequest.open('GET', this._getServerUrl(), true);
        JsHttpRequest.clearTimeout(this.timeout);
        this.timeout = JsHttpRequest.setTimeout((function() {
            var request = this.options.requestParams || {};
            request.q = this.node.value;
            if (request.q.length > 0) {
                this.showIndicator();
                this.JsHttpRequest.send(request);
                this.onRequestSent();
            } else {
                this.showInvitation();
            }
        }).bind(this), 300);
    },

    bindEvents: function() {
        this.boundOnFocus = this.onNodeFocus.bind(this);
        this.boundOnBlur = this.onNodeBlur.bind(this);

        Event.observe(this.node, "focus", this.boundOnFocus);
        Event.observe(this.node, "blur", this.boundOnBlur);
        Event.observe(window, "resize", this.updateListPosition.bindAsEventListener(this));
        
        var event;
        if (Prototype.Browser.Gecko || Prototype.Browser.Opera) {
            event = "keypress";
        } else {
            event = "keydown";
        }
        Event.observe(this.node, event, this.onNodeKeyDown.bindAsEventListener(this));
        Event.observe(this.node, "keyup", this.onNodeKeyUp.bindAsEventListener(this));
        return this;
    },

    onNodeFocus: function() {
        this.nodeBlurred = false;
        if (this.node.value.length === 0) {
            this.showInvitation();
        }
        this.onFocus();
    },

    onNodeBlur: function() {
        this.nodeBlurred = true;
        var th = this;
        JsHttpRequest.setTimeout(function() {
            if (th.nodeBlurred) {
                th.onBlur();
            }
        }, 200);
    },

    onNodeKeyDown: function(e) {
        this.waitingForKeyPress = false;
        var code = e.keyCode;

        switch (code) {
            case Event.KEY_BACKSPACE:
                if (this.onNodeBackspaceKey(e)) {
                    return;
                }
                break;
            case Event.KEY_ESC:
                if (this.onNodeEscapeKey(e)) {
                    return;
                }
                break;
            case Event.KEY_UP:
                if (this.onNodeUpKey(e)) {
                    return;
                }
                break;
            case Event.KEY_DOWN:
                if (this.onNodeDownKey(e)) {
                    return;
                }
                break;
            case Event.KEY_RETURN:
                if (this.onNodeEnterKey(e)) {
                    return;
                }
                break;
            case Event.KEY_TAB:
                if (this.onNodeTabKey(e)) {
                    return;
                }
                break;
        }
        this.waitingForKeyPress = true;
    },

    onNodeBackspaceKey: function() {
        this.hideList();
    },

    onNodeEscapeKey: function(e) {
        this.hideList();
        Event.stop(e);
        return true;
    },

    onNodeUpKey: function(e) {
        if (this.list.childNodes.length > 0 && this.list.firstChild.className != "invitation") {

            this.resetSelection();

            switch (this.preSelectedElementIndex) {
                case null:
                    this.preSelectedElementIndex = this.list.childNodes.length - 1;
                    break;
                case 0:
                    this.preSelectedElementIndex = null;
                    this.node.value = this.oldReqValue;
                    break;
                default:
                    this.preSelectedElementIndex--;
                    break;
            }

            if (this.preSelectedElementIndex !== null) {
                $(this.list.childNodes[this.preSelectedElementIndex]).addClassName(this.options.selectedClassName);
                if (this.options.updateInputOnLoopingThru) {
                    this.node.value = this.list.childNodes[this.preSelectedElementIndex].title;
                }
                this.node.dic_id = this.list.childNodes[this.preSelectedElementIndex].dic_id;
                this.selectedItem = this.list.childNodes[this.preSelectedElementIndex];
            }
            Event.stop(e);
            return true;
        }
    },

    onNodeDownKey: function(e) {
        if (this.list.childNodes.length > 0 && this.list.firstChild.className != "invitation") {
            
            this.resetSelection();

            switch (this.preSelectedElementIndex) {
                case null:
                    this.preSelectedElementIndex = 0;
                    break;
                case this.list.childNodes.length - 1:
                    this.preSelectedElementIndex = null;
                    this.node.value = this.oldReqValue;
                    break;
                default:
                    this.preSelectedElementIndex++;
                    break;
            }

            if (this.preSelectedElementIndex !== null) {
                this.list.childNodes[this.preSelectedElementIndex].addClassName(this.options.selectedClassName);
                if (this.options.updateInputOnLoopingThru) {
                    this.node.value = this.list.childNodes[this.preSelectedElementIndex].title;
                }
                this.node.dic_id = this.list.childNodes[this.preSelectedElementIndex].dic_id;
                this.selectedItem = this.list.childNodes[this.preSelectedElementIndex];
            }
            Event.stop(e);
            return true;
        }
    },

    onNodeEnterKey: function(e) {
        Event.stop(e);
        this.onEnterKey();
        if (this.selectedItem) {
            this.selectItem(this.selectedItem);
        }
        return true;
    },

    onEnterKey: function() {

    },

    onNodeTabKey: function(e) {
        if (this.preSelectedElementIndex !== null && this.list.childNodes.length > 0 && this.node.value == this.list.childNodes[this.preSelectedElementIndex].title) {
            if (this.selectedItem) {
                this.selectItem(this.selectedItem);
            }
            return true;
        } else {
            this.hideList();
            return true;
        }
    },

    onNodeKeyUp: function() {
        if (this.waitingForKeyPress) {
            this.requestList();
        }
    },

    onRequestSent: function() {

    },
    
    onFocus: function() {
    },

    onBlur: function() {
        if (this.JsHttpRequest) {
            this.JsHttpRequest.onreadystatechange = null;
        }
        this.hideIndicator();
        if (!this.options.showInvitationOnBlur) {
            this.hideList();
        }
    },

    fillList: function(jsList) {
        this.clearList();
        if (jsList.length) {
            var search = this.node.value;
            for (var idx = 0,I = jsList.length; idx < I; idx++) {
                if (jsList[idx].size && jsList[idx].size > 0) {
                    this.addListItem(jsList[idx], search);
                }
            }
        }
    },

    addListItem: function(rawListItem, search) {
        var li = document.createElement('li');
        var highlightedName = this.getHighlightedValue(rawListItem, search);
        /*
        var sizeSpan = '<span class="count">' + rawListItem.size + '</span>';
        if (this.options.countless) {
            sizeSpan = '<span class="count">&nbsp;</span>';
        }
        */
        li.innerHTML = highlightedName;
        li.title = rawListItem.name;
        li.dic_id = rawListItem.id;
        this.list.appendChild(li);
        this.initListItem(li);
    },
    
    initListItem: function(listItem) {
        var that = this;
        Event.observe(listItem, 'click', ((function(e) {
            this.selectItem(listItem);
        }).bindAsEventListener(this)));
        listItem.onmouseover = (function() {
            this.resetSelection();
            listItem.addClassName(this.options.hoverClassName);
        }).bind(this);
        listItem.onmouseout = function() { this.removeClassName(that.options.hoverClassName); };
    },
    
    resetSelection: function (){
        if (this.list.childNodes.length > 0){
            for (var i=0,l=this.list.childNodes.length;i<l;i++) {
                if (this.list.childNodes[i].className){
                    this.list.childNodes[i].removeClassName(this.options.hoverClassName);
                    this.list.childNodes[i].removeClassName(this.options.selectedClassName);
                }
            }
        }
    },

    getHighlightedValue: function(value, searchSubstr) {
        var name = value.name;
        var substrIdx = name.toLowerCase().indexOf(searchSubstr.toLowerCase());
        var highlightedName;
        if (substrIdx > -1) {
            highlightedName = name.substr(0, substrIdx);
            highlightedName += "<span class=\"highlight\">" + name.substr(substrIdx, searchSubstr.length).escapeHTML() + "</span>";
            highlightedName += name.substr(substrIdx + searchSubstr.length).escapeHTML();
        } else {
            highlightedName = name;
        }
        return highlightedName;
    },

    clearList: function() {
        while (this.list.childNodes.length > 0) {
            this.list.removeChild(this.list.firstChild);
        }
        this.selectedItem = null;
    },
    
    /**
     * Displays invitation
     * 
     * In the case showInvitation flag is set to FALSE
     * we have an opportunity to show invitation on demand
     * by passing optional parameter
     * 
     * @param {Boolean} showOnDemand
     */
    showInvitation: function(showOnDemand) {
        if (this.options.showInvitation || !!showOnDemand) {
               this.clearList();
            var li = document.createElement('li');
            $(li).addClassName("invitation");
            li.appendChild(document.createTextNode(this.invitation));
            this.list.appendChild(li);
            this.showList();
        }
    },

    selectItem: function(listItem) {
        this.selectedItem = listItem;
        this.node.value = listItem.title;
        this.node.dic_id = listItem.dic_id;
        this.node.focus();
        this.hideList();
        this.onItemSelected();
    },

    onItemSelected: function() {
    }

});
;

/**** /js/moikrug/ui/messaging/PersonSuggest.js ****/
Lang.module("moikrug.ui.messaging.PersonSuggest");

Lang.include("common.TextUtils");
Lang.include("moikrug.ui.Suggest");

moikrug.ui.messaging.PersonSuggest = Lang.createClass(moikrug.ui.Suggest, {

    init: function(node, options, name, className) {
        this.baseConstructor(node, options, name, className);
        this._template = new Template(
            '<div class="person person_middle"><div class="avatar">' + 
            '<div class="person_photo_container person_photo_container_middle profilePreview">' +
            '<img src="#{photo}" class="person_photo">' + '<div class="person_border"></div>' +
            '#{online}' + 
            '</div></div><div class="info"><div class="name">' +
            '#{name}</div>' +
            '<div class="slogan">#{motto}</div>' +
            '</div><div class="wrap"></div></div>'
        );
        this._onlineStatus = '<div class="person_border_online"></div>';
    },

    createList: function() {
        var list = document.createElement("ul");
        list.className = "suggest-list PersonSuggestList";
        list.style.display = "none";
        return list;
    },
    
    fillList: function(jsList) {
        this.clearList();
        if (jsList.length) {
            var search = this.node.value;
            for (var idx = 0,I = jsList.length; idx < I; idx++) {
                this.addListItem(jsList[idx], search);
            }
        }
    },

    updateListWidth: function(){},

    onNodeUpKey: function(e) {
        if (this.list.childNodes.length > 0 && this.list.firstChild.className != "invitation") {

            this.resetSelection();

            switch (this.preSelectedElementIndex) {
                case null:
                    this.preSelectedElementIndex = this.list.childNodes.length - 1;
                    break;
                case 0:
                    this.preSelectedElementIndex = null;
                    this.node.value = this.oldReqValue;
                    break;
                default:
                    this.preSelectedElementIndex--;
                    break;
            }

            if (this.preSelectedElementIndex !== null) {
                $(this.list.childNodes[this.preSelectedElementIndex]).addClassName("selected");
				this.selectedItem = this.list.childNodes[this.preSelectedElementIndex];
            }
            Event.stop(e);
            return true;
        }
    },

    onNodeDownKey: function(e) {
        if (this.list.childNodes.length > 0 && this.list.firstChild.className != "invitation") {

            this.resetSelection();

            switch (this.preSelectedElementIndex) {
                case null:
                    this.preSelectedElementIndex = 0;
                    break;
                case this.list.childNodes.length - 1:
                    this.preSelectedElementIndex = null;
                    this.node.value = this.oldReqValue;
                    break;
                default:
                    this.preSelectedElementIndex++;
                    break;
            }

            if (this.preSelectedElementIndex !== null) {
                this.list.childNodes[this.preSelectedElementIndex].addClassName("selected");
				this.selectedItem = this.list.childNodes[this.preSelectedElementIndex];
            }
            Event.stop(e);
            return true;
        }
    },

    requestList: function() {
		if (this.node.value.length === 0) {
            this.hideList();
            this.hideIndicator();
            this.showInvitation();
            JsHttpRequest.clearTimeout(this.timeout);
            return;
        }
        this.oldReqValue = this.node.value;
        this.JsHttpRequest = new JsHttpRequest();
        this.JsHttpRequest.onreadystatechange = (function() {
            if (this.JsHttpRequest.readyState != 4) {
                return;
            }
            this.hideList();
            this.fillList(this.JsHttpRequest.responseJS);
            this.showList();
            this.hideIndicator();
        }).bind(this);
        this.JsHttpRequest.caching = true;
        this.JsHttpRequest.open('GET', this._getServerUrl(), true);
        JsHttpRequest.clearTimeout(this.timeout);
        this.timeout = JsHttpRequest.setTimeout((function() {
            var request = this.options.requestParams || {};
            request.request = this.node.value;
            if (request.request.length > 0) {
                this.showIndicator();
                this.JsHttpRequest.send(request);
                this.onRequestSent();
            } else {
                this.showInvitation();
            }
        }).bind(this), 300);
	},
    
    _getListItemHtml: function(dataItem, searchString) {
        var templateData = {};
        templateData.photo = dataItem.photo || "/images/blank_photo/blank_photo_30px.png";
        templateData.motto = dataItem.resume_headline;
        templateData.online = dataItem.is_online ? this._onlineStatus : "";
        templateData.name = common.TextUtils.highlightFirstLetterInName(
            common.TextUtils.highlightSearchString(dataItem.displayname, searchString)
        );
        return this._template.evaluate(templateData);
    },

    addListItem: function(dataItem, searchString) {
        if (this.options.validate && !this.options.validate(dataItem)) {
            return;
        }
        var html = this._getListItemHtml(dataItem, searchString);
        var li = document.createElement('li');

        li.innerHTML = html;
        li.title = dataItem.displayname;
        li.dic_id = dataItem.id;
        this.list.appendChild(li);
        Event.observe(li, 'click', ((function(e) {
            this.selectItem(li);
        }).bindAsEventListener(this)));
        li.onmouseover = (function() {
            this.resetSelection();
            li.addClassName("hover");
        }).bind(this);
        li.onmouseout = function() { this.removeClassName("hover"); };
    },

    selectItem: function(listItem)  {
        this.node.focus();
        this.hideList();
        this.onItemSelected(listItem);
    },
    
    _createClonedWidget: function(node, options, widgetName, widgetClassName) {
        return new moikrug.ui.PersonSuggest(node, options, widgetName, widgetClassName);
    }

});
;

/**** /js/moikrug/ui/GrowingInput.js ****/
Lang.module('moikrug.ui.GrowingInput');

Lang.include('Widget');

moikrug.ui.GrowingInput = Lang.createClass(Widget, {
	init: function(node, options) {
		this.baseConstructor(node, options);
        this.interval = 0;
	},
    
    bindEvents: function() {
        Event.observe(this.node, "keyup", this._onKeyUp.bind(this));
        //Event.observe(this.node, "keydown", this._onKeyDown.bind(this));
        return this;
	},
    
    _onKeyUp: function() {
        this._updateWidth();
    },
    
    _updateWidth: function() {
        var newWidth = this._getTextWidth();
        this.node.style.width = newWidth + 'px';
    },
    
    _getTextWidth: function() {
        var span = this._getContainer();
        var value = this.node.value;
        span.innerHTML = this._updateText(value.replace(/ {2}/g, ' &nbsp;'));
        return span.offsetWidth;
    },

    _updateText: function(text) {
        return text + "m";
    },
    
    _getContainer: function() {
        if (!this._container) {
            this._container = document.createElement("span");
            this._container.style.position = "absolute";
            this._container.style.left = "-9999px";
            
            this._syncStyles(this.node, this._container);
            this.node.parentNode.appendChild(this._container);
        }
        this._container.innerHTML = '';
        return this._container;
    },
    
    _syncStyles: function(src, target) {
        $w('fontFamily fontSize ' +
           'paddingLeft paddingRight ' +
           'borderLeftWidth borderRightWidth ' + 
           'borderLeftStyle borderRightStyle').each(function(s) {
            target.style[s] = src.getStyle(s);
        });
    }
});
;

/**** /js/moikrug/UserPage.js ****/
Lang.module('moikrug.UserPage');

moikrug.UserPage = Lang.createClass(Page, {
    init: function() {
        this.baseConstructor();
        var factFormElement = $$('.statement_add_form');
        if (factFormElement.length) {
            this.factForm = WidgetRegistry.get(factFormElement[0]);
            this.factFormShowLink = $('statement_add_form_show');
        } 
        
        var formElement = $$('.message_form');
        if (formElement.length) {
            formElement = formElement[0];
            this.form = WidgetRegistry.get(formElement);
            if (this.form) {
                this.formShowLink = $('message_form_show');
		        this.formHideLink = $('message_form_hide');
		        this.notification = $('MessageForm_message_notification');
            }   
        } 
        this.bindEvents();
    },
    
    bindEvents: function() {
    	if (this.formShowLink && this.formHideLink) {
	        Event.observe(this.formShowLink, "click", this.showForm.bind(this));
	        Event.observe(this.formHideLink, "click", this.hideForm.bind(this));
        }
        if (this.factForm) {
        	this.factForm.onHideForm = this.hideFactForm.bind(this);
	        Event.observe(this.factFormShowLink, "click", this.showFactForm.bind(this));
        }
    },
    
    showForm: function() {
        if (this.notification) {
            this.notification.hide();
        }
        this.formShowLink.addClassName("hidden");
        this.formHideLink.removeClassName("hidden");
        this.form.showForm();
    },
    
    hideForm: function() {
        this.formShowLink.removeClassName("hidden");
        this.formHideLink.addClassName("hidden");
        this.form.hideForm();
    },
    
    showFactForm: function() {
    	this.factFormShowLink.addClassName("hidden");
        this.factForm.showForm();
    },
    
    hideFactForm: function() {
        this.factFormShowLink.removeClassName("hidden");
    }
    
});
;

/**** /js/moikrug/widget/Label/Controller.js ****/
/**
 * @author ilazarev
 * @requires moikrug.Widget
 */
Lang.module('moikrug.widget.Label.Controller');
 

/**
 * @class moikrug.widget.Label.Control
 */
moikrug.widget.Label.Controller = Lang.createClass(null, {

	init: function (dropdownWidget, editWidget) {

		// handle action in dropdown
		dropdownWidget.addHandler('label_action_add', function() {
			editWidget.moveBlockUnderElement(dropdownWidget.node);
			editWidget.showBlock();
		});
		
		dropdownWidget.clickHook = dropdownWidget.clickHook.wrap(function(wrapped) {
			editWidget.hideBlock();
			dropdownWidget.resetSelection();
		});
		
		// hanlde "cancel" in Edit 
		editWidget.cancelHook = editWidget.cancelHook.wrap(function(wrapped) {
			dropdownWidget.resetSelection();
			return wrapped();
		});
		
		// set correct se
		if (editWidget.isVisible()) {
			window.load[window.load.length] = 
			function() {
				editWidget.moveBlockUnderElement(dropdownWidget.node); 
			};
			dropdownWidget.setSelectionToAction('label_action_add');
		}
		
	}
});


;

/**** /js/moikrug/Widget.js ****/
Lang.module('moikrug.Widget');

Lang.include('moikrug.widget.Registry');

moikrug.Widget = Lang.createClass(Widget, {
	init: function(node, options, name, className) {
		this.baseConstructor(node, options);
		this.widgetClassName = className;
		this.widgetName = name;
		this.childWidgets = [];
		this.parentWidget = null;
	},
	
	getWidgetName: function() {
		return this.widgetName;
	},
	
	getWidgetClassName: function() {
		return this.widgetClassName;
	},
	
	/**
	 * @return moikrug.Widget
	 */
	getParentWidget: function() {
		return this.parentWidget;
	},
	
	/**
	 * @param {moikrug.Widget} widget
	 */
	setParentWidget: function(widget) {
		this.parentWidget = widget;
	},
	
	/**
	 * @param {moikrug.Widget} widget
	 */
	addChildWidget: function(widget) {
		this.childWidgets.push(widget);
		if (widget.setParentWidget) {
			widget.setParentWidget(this);
		}
	},
	
	/**
	 * @param {moikrug.Widget} widget
	 */
	removeChildWidget: function(widget) {
		this.childWidgets = this.childWidgets.without(widget);
		widget.setParentWidget(null);
	},
	
	getChildWidgetsAsString: function() {
		var widgets = [];
		for (var i in this.childWidgets) {
			if (this.childWidgets.hasOwnProperty(i)) {
				var widget = this.childWidgets[i];
				if (!widget) {
					continue;
				}
				if (!(widget instanceof moikrug.Widget)) {
					continue;
				}
	
				widgets.push(widget);
			}
		}
		return widgets.map(function(widget) {
			return widget.getWidgetName() + ':' + widget.getWidgetClassName();
		}).join(';');	
	}
	
});
;

/**** /js/moikrug/widget/profile/LookingForJob.js ****/
Lang.module('moikrug.widget.profile.LookingForJob');

moikrug.widget.profile.LookingForJob = Lang.createClass(moikrug.Widget, {
    init: function(node, options, name, className) {
        this.defaults = options.defaults;
        this.baseConstructor(node, options, name, className || 'profile.LookingForJob');
    },
    
    parse: function() {
        this.jobNode = this.node.down('.job_view');
        this.settingsNode = this.node.down('.job_settings');
        this.linkNode = this.node.down('.job_edit_link');
        this.cancelNode = this.node.down('.job_cancel_link');
        
        this.checkboxNode = this.node.down('.looking_for_job_checkbox');
        this.salaryNode = this.node.down('.looking_for_job_min_salary');
        this.currencyNode = this.node.down('.looking_for_job_currency');
        this.keywordsNode = this.node.down('.looking_for_job_keywords');    
        return this;
    },
    
    bindEvents: function() {
        if (this.linkNode) {
        	this.linkNode.observe('click', this._onShow.bindAsEventListener(this));
        }
        if (this.cancelNode) {
        	this.cancelNode.observe('click', this._onHide.bindAsEventListener(this));
        }
        if (this.checkboxNode && !this.checkboxNode.checked) {
	        this.checkboxNode.observe('click', function (event) { 
	            if (this.checkboxNode.checked) {
	            	this._onSetLookingForJob(event);
	            }
	        }.bindAsEventListener(this));
        }
        return this;
    },
    
    _onShow: function(event) {
        event.stop();
        this.jobNode.hide();
        this.linkNode.addClassName('hidden');
        if (this.settingsNode) {
        	this.settingsNode.removeClassName('hidden');
        }
    },
    
    _onSetLookingForJob: function (event) {
        var salary = '';
        if (!this.salaryNode.value) {
	        if (this.defaults.salary_from) {
	            salary = this.defaults.salary_from;
	        } else if (!this.defaults.salary_from && this.defaults.salary_to) {
	            salary = this.defaults.salary_to;
	        }
	        this.salaryNode.value = salary;
        }
        
        if (salary && this.defaults.salary_currency) {
            this.currencyNode.value = this.defaults.salary_currency;
        }
        
        if (this.defaults.keywords && !this.keywordsNode.value) {
            this.keywordsNode.value = this.defaults.keywords;
        }
    },

    _onHide: function(event) {
        event.stop();
        this.jobNode.show();
        this.linkNode.removeClassName('hidden');
        if (this.settingsNode) {
        	this.settingsNode.addClassName('hidden');
        }
    }
    
});
;

/**** /js/moikrug/ui/GrowingTextarea.js ****/
Lang.module('moikrug.ui.GrowingTextarea');

Lang.include('Widget');

moikrug.ui.GrowingTextarea = Lang.createClass(Widget, {
	init: function(node, options) {
		this.baseConstructor(node);
        this.heightSaved = false;
        this.saveHeightTimeout = 0;
	},
    
    parse: function() {
        this.saveHeight();
        this.node.style.overflowY = "hidden";
        this._updateHeight();
        return this;
    },
    
    onHeightUpdate: function(){},
	
	bindEvents: function() {
        Event.observe(this.node, "keyup", this._updateHeight.bind(this));
        return this;
	},
    
    saveHeight: function() {
        this.saveHeightTimeout = window.setInterval((function() {
            if (this.node.offsetHeight) {
                this.originalOffsetHeight = this.node.offsetHeight;
                this.originalStyleHeight = this.node.getStyle('height');
                this.heightSaved = true;
                window.clearInterval(this.saveHeightTimeout);
            }
        }).bind(this), 50);
    },
    
    _getEmSize: function() {
        if (!this.emSize) {
            var textarea = document.createElement("textarea");
            textarea.style.border = "0";
            textarea.style.height = "2em";
            textarea.style.padding = "0";
            textarea.style.visibility = "hidden";
            this.node.parentNode.appendChild(textarea);
            var height = textarea.offsetHeight;
            textarea.parentNode.removeChild(textarea);
            this.emSize = height / 2;
        }
        return this.emSize;
    },
    
    _updateHeight: function() {
        if (!this.heightSaved) {
            window.setTimeout(this._updateHeight.bind(this), 100);
            return;
        }
        if (this.needWidthUpdate && this.node.offsetWidth) {
            var div = this._getContainer();
            div.style.width = this.node.offsetWidth - this.additional + "px";
            this.needWidthUpdate = false;
        }
        var newHeight = this._getTextHeight();
        if (newHeight > this.originalOffsetHeight + 5) {
            this.node.style.height = newHeight + 'px';
        } else {
            if (Prototype.Browser.Opera) {
                this.node.style.height = this.originalOffsetHeight + "px";
            } else {
                this.node.style.height = this.originalStyleHeight;
            }
        }
    },
    
    _getTextHeight: function() {
        if (Prototype.Browser.IE) {
            return this.node.scrollHeight + 2 * this._getEmSize();
        } else {
            var div = this._getContainer();
            var value = this.node.value;
            if (this.previousValue) {
                var newNewLinesRegexp = value.match(/\n+$/);
                var newNewLines = newNewLinesRegexp ? newNewLinesRegexp[0].length : 0;
                var oldNewLinesRegexp = this.previousValue.match(/\n+$/);
                var oldNewLines = oldNewLinesRegexp ? oldNewLinesRegexp[0].length : 0;
                if (newNewLines - oldNewLines == 2) {
                    value = value.substr(0, value.length - 1);
                }
            }
            if (Prototype.Browser.WebKit) {
                this.previousValue = value;
            }
            div.innerHTML = value.replace(/</g, '&lt;').replace(/ {2}/g, ' &nbsp;').replace(/\n/g, '<br/>t') + "<br/>t<br/>t";
            return div.offsetHeight;
        }
    },
    
    _getContainer: function() {
        if (!this._container) {
            this._container = document.createElement("div");
            this._container.style.position = "absolute";
            this._container.style.left = "-9999px";
            
            this._syncStyles(this.node, this._container);
            this.node.parentNode.appendChild(this._container);
        }
        this._container.innerHTML = '';
        return this._container;
    },
    
    _syncStyles: function(src, target) {
        if (Prototype.Browser.Opera) {
            src.style["lineHeight"] = src.getStyle("lineHeight");
            this.needWidthUpdate = true;
        }
        $w('fontFamily fontSize lineHeight ' +
           'paddingLeft paddingRight paddingTop paddingBottom ' +
           'borderLeftWidth borderRightWidth borderTopWidth borderBottomWidth ' + 
           'borderLeftStyle borderRightStyle borderTopStyle borderBottomStyle ' +
           'lineHeight width').each(function(s) {
            target.style[s] = src.getStyle(s);
        });
        if (Prototype.Browser.Opera) {
            this.additional = 20;
        }
        if (Prototype.Browser.Gecko) {
            this.additional = 10;
        }
        if (Prototype.Browser.WebKit) {
            this.additional = 4;
        }
        if (this.additional) {
            target.style.width = parseFloat(target.style.width) - this.additional + "px";
        }
    }
});
;

/**** /js/moikrug/ui/MessageForm.js ****/
Lang.module('moikrug.ui.MessageForm');
Lang.include('common.FormUtils');

moikrug.ui.MessageForm = Lang.createClass(moikrug.Widget, {
    init: function(node, options, name) {
        this.baseConstructor(node, options, name);
    },
    
    parse: function() {
        this.textInput = this.node.down('.message_message');
        this.textInputWidget = WidgetRegistry.get(this.textInput);
        this.textLabel = this.textInput.up().down("label");
        
        this.showControl = this.node.down(".message_form_show");
        this.hideControl = this.node.down(".message_form_hide");
        
        this.hasControls = !!this.showControl;
        this.form = this.node.down("div") || this.node.down("form");
        this.formShown = !this.form.hasClassName("hidden");

        this.recipientListShow = this.node.down(".message_form_recipients_show");
        this.recipientList = this.node.down(".message_form_recipients");
        return this;
    },
    
    getControlls: function() {
        return { show: this.showControl, hide : this.hideControl };
    },
    
    toggleForm: function() {
        this.formShown = !this.formShown;
        if (this.formShown) {
            this.showForm();
        } else {
            this.hideForm();
        }
    },
    
    showForm: function() {
        this.form.removeClassName("hidden");
        this.form.style.zoom = 1;
        if (this.hasControls) {
            this.showControl.addClassName("hidden");
            this.hideControl.removeClassName("hidden");
        }
        this.textInput.focus();
    },
    
    hideForm: function() {
        this.form.addClassName("hidden");
        if (this.hasControls) {
            this.hideControl.addClassName("hidden");
            this.showControl.removeClassName("hidden");
        }
    },

    bindEvents: function() {
        common.FormUtils.placeholder(this.textInput, this.textLabel);
        if (this.recipientListShow) {
            Event.observe(this.recipientListShow, "click", (function(e) {
                e.stop();
                this.recipientListShow.addClassName("hidden");
                this.recipientList.removeClassName("hidden");
                var wList  = WidgetRegistry.get(this.recipientList.down());
                if (wList) {
                    wList.setFocus();
                }
            }).bindAsEventListener(this));
        }
        if (this.hasControls) {
            Event.observe(this.showControl, "click", this.toggleForm.bind(this));
            Event.observe(this.hideControl, "click", this.toggleForm.bind(this));
        }
        return this;
    },

    setRecipientPerson: function(person_id) {
        $('recipients_persons').value = person_id;
    }
});

;

/**** /js/form/Form.js ****/
Lang.module('form.Form');

Lang.include('moikrug.widget.Clonable');

form.Form = Lang.createClass(moikrug.widget.Clonable, {
    init: function(node, options, name, className) {
        this.baseConstructor(node, options, name, className);
        this.controlSubmit = {};
    },

    parse: function() {
        var tmp = this.node.down('input[type="submit"]') || this.node.down('button[type="submit"]');
        this.controlSubmit = Widget.getInstance(tmp) || tmp;
    },

    setDisabled: function(state) {
        if(this.controlSubmit.setDisabled) {
        	this.controlSubmit.setDisabled(state);
        } else {
        	this.controlSubmit.disabled = state;
        }
    },

    isDisabled: function() {
        return this.controlSubmit.disabled;
    },

    bindEvents: function() {
        Event.observe(this.node, 'submit', this.onFormSubmit.bindAsEventListener(this));
    },

    onFormSubmit: function(event) {
        this.onSubmit();
    },

    onSubmit: function() {
    }
});

form.Form.getInstance = function(node) {
    return Widget.getInstance(node) || Widget.registerInstance(node, new form.Form(node));
};

;

/**** /js/form/SubmitableForm.js ****/
Lang.module('form.SubmitableForm');

Lang.include('form.Form');

form.SubmitableForm = Lang.createClass(form.Form, {
    init: function(node, options, name, className) {
        this.baseConstructor(node, options, name, className);
    },

    parse: function() {
        this.textareas = this.node.select('textarea');
        return this;
    },
    
    bindEvents: function() {
        for (var i=0; i < this.textareas.length; i++) {
	        Event.observe(this.textareas[i], 'keydown', this.submitForm.bindAsEventListener(this));
	    }
	    return this;
    },
	
    submitForm: function(event) {
        if (
            (event.ctrlKey || event.metaKey) 
            && event.keyCode == Event.KEY_RETURN
        ) {
            this.node.submit();
        }
    }
	
});

;

/**** /js/common/FormUtils.js ****/
Lang.module('common.FormUtils');

common.FormUtils = {
    
    placeholder: function(node, textOrLabel, options) {
         this.options = options || {};
         
         this.isSpanHeightRequired = this.options.hasOwnProperty("isSpanHeightRequired") ? this.options.isSpanHeightRequired : true;
         
         if (!$(node)) {
             return;
         }
         if (!textOrLabel && $(node + '_label')) { 
            this._placeholderLabel($(node), $(node + '_label'));
        } else if ($(textOrLabel)) {
            this._placeholderLabel($(node), $(textOrLabel));
        } else if (textOrLabel) {
            this._placeholderText($(node), textOrLabel);
        }
    },

    getLabel: function(input) {
        for (var i=0,I=this._inputs.length;i<I;i++) {
            if (this._inputs[i] == input) {
                return this._labels[i];
            }
        }
        return null;
    },
    
    _inputs: [],
    _labels: [],
    _cleanerLaunched: false,
    
    _cleaner: function() {
        for (var i=0,I=this._inputs.length; i<I; i++) {
            //noinspection BadExpressionStatementJS
            if (this._inputs[i] && !!this._inputs[i].value.length) {
                this._labels[i].style.display = "none";
            }
        }
    },
    
    _placeholderLabel: function(node, label)
    {
        this._inputs[this._inputs.length] = node;
        this._labels[this._labels.length] = label;
        Event.observe(node, "focus", function() {
             label.style.display = "none";
        });
        Event.observe(node, "blur", function() {
            if (node.value.strip() === "") {
                label.style.display = "block";
            }
        });
        Event.observe(label, "click", function() {
            node.focus();
        });
        if (!this._cleanerLaunched) {
            this._cleanerLaunched = true;
            window.setInterval(this._cleaner.bind(this), 100);
        }
    },
    
    _placeholderText: function(node, text) {
        Element.wrap(node, 'span').setStyle({
            position: 'relative',
            top: '0', 
            left: '0', 
            display: 'block', 
            height: this.isSpanHeightRequired ? "1%" : ""
        });
        
        var label = new Element('label', {'for': node.id});
        label.innerHTML = text;
        label.setStyle({
            position: 'absolute',
            top: this.options.top || '1px', 
            left: '4px',
            display: 'block',
            lineHeight: '1.4em',
            cursor: 'text',
            color: '#999',
            zIndex: '2',
            whiteSpace: 'nowrap'
        });
        node.insert({before: label});
        this._placeholderLabel(node, label);
    }
};

;

/**** /js/moikrug/widget/profile/StatementList.js ****/
Lang.module('moikrug.widget.profile.StatementList');

moikrug.widget.profile.StatementList = Lang.createClass(moikrug.Widget, {
    init: function(node, options, name, className) {
        if (options.statements) {
            this.statements = $H(options.statements);
        } else {
            this.statements = $H({});
        }
        this.node = node;
        
        this.baseConstructor(node, options, name, className || 'profile.StatementList');
    },
    
    parse: function() {
    	this.confirmedListContainer = $('confirmed_list_container');
    	this.unconfirmedListContainer = $('unconfirmed_list_container');
    	
    	this.confirmedListNode = $$('.confirmed_list')[0];
    	this.unconfirmedListNode = $$('.unconfirmed_list')[0];
        this.listNode = this.node.down('.expandable_list_confirmed');
        this.expandNode = this.node.down('.expand_confirmed');
        this.placeholder = this.node.down('.profile_edit_placeholder');
        return this;
    },
    
    bindEvents: function() {
    	if (this.expandNode) {
    		this.expandNode.observe('click', this._onExpand.bind(this));
    	}
    	
	  	this.statements.each(function(pair) {
		    var statement = pair.value;
		    
		    var checkContainersAfterStatamentChange = function(statement) {
		    	// if all statement denied from unconfirmed list - hide list
				if (statement.node.descendantOf(this.unconfirmedListContainer)) {
				    this.checkContainerEmpty(this.unconfirmedListContainer);
				}
				// if all statement denied from confirmed list - hide list
				else if (statement.node.descendantOf(this.confirmedListContainer)) {
					console.log(231);
					this.checkContainerEmpty(this.confirmedListContainer);
				}
		    	
				this.checkAllListsEmpty();
		    }.bind(this);
		    
		    statement._onUnvotedPersonal = (function(unsetted_statement) {
		       	checkContainersAfterStatamentChange(statement);
		    }).bind(this);
		    
		    statement._onUnapproveHook = (function() {
                // checkContainersAfterStatamentChange(statement);
		    	this.unconfirmedListNode.insert(statement.node);
		    	
		    	if (this.unconfirmedListContainer.hasClassName('hidden')) {
		    		this.unconfirmedListContainer.removeClassName('hidden');	
		    	}

		    	this.checkContainerEmpty(this.confirmedListContainer);
		    	
		    }).bind(this);

		    statement._onDenyHook = (function() {
                checkContainersAfterStatamentChange(statement);
		    }).bind(this);

		    statement._onApproveHook = (function() {
		    	this.confirmedListNode.insert(statement.node);
		    	
		    	if (this.confirmedListContainer.hasClassName('hidden')) {
		    		this.confirmedListContainer.removeClassName('hidden');	
		    	}

		    	this.checkContainerEmpty(this.unconfirmedListContainer);
		    	
		    }).bind(this);
		    
		}.bind(this));
    	
        return this;
    },
    
    /**
     * check if all lists of statement is hidden and show placeholder
     */
    checkAllListsEmpty : function() {
    	if (this.unconfirmedListContainer.hasClassName('hidden') 
    		&& this.confirmedListContainer.hasClassName('hidden')) {
    		this.placeholder.removeClassName('hidden');
    	}
    },
    
    checkContainerEmpty: function(containerNode) {
    	var isHiddenElement = function(e) {
    		return e.hasClassName('hidden');
    	};
    	if (containerNode.select('.statement').all(isHiddenElement)) {
			containerNode.addClassName('hidden');
    	}
    },
    
    _onExpand: function() {
        this.expandNode.addClassName('hidden');
        this.listNode.removeClassName('hidden');
    }

   
});

var statement_list = {};
;

/**** /js/moikrug/widget/profile/Statement.js ****/
Lang.module('moikrug.widget.profile.Statement');

moikrug.widget.profile.Statement = Lang.createClass(moikrug.Widget, {
    init: function(node, options, name, className) {
		this.statementId = options.statementId;
        this.url = options.url;
        this.disabled = false;
        this.personal = options.personal || false;
        this.baseConstructor(node, options, name, className || 'profile.Statement');
        this.denyStatementMessage = DIC['delete_statement_confirm_message'];
    },
    
    parse: function() {
        this.approveNode = this.node.down('.approve_button');
        this.unapproveNode = this.node.down('.unapprove_button');
        this.denyNode = this.node.down('.deny_button');
        this.voteNode = this.node.down('.vote_button');
        this.unvoteNode = this.node.down('.unvote_button');
        this.peopleButtonNode = this.node.down('.people_amount');
        this.listNode = this.node.down('.people_list');
        this.andYouNode = this.node.down('.and_you');
        return this;
    },
    
    bindEvents: function() {
    	if (this.approveNode) {
    		this.approveNode.observe('click', this._onApproveClick.bindAsEventListener(this));
    	}
    	if (this.unapproveNode) {
    		this.unapproveNode.observe('click', this._onUnapproveClick.bindAsEventListener(this));
    	}
    	if (this.denyNode) {
    		this.denyNode.observe('click', this._onDenyClick.bindAsEventListener(this));
    	}
    	if (this.voteNode) {
    		this.voteNode.observe('click', this._onVoteClick.bindAsEventListener(this));
    	}
    	if (this.unvoteNode) {
    		this.unvoteNode.observe('click', this._onUnvoteClick.bindAsEventListener(this));
    	}
    	if (this.peopleButtonNode) {
    		this.peopleButtonNode.observe('click', this._onPeopleClick.bindAsEventListener(this));
    	}
        return this;
    },
    
    _onVoteClick: function() {
        if (this.disabled) {
        	return;
        }
        this._query({action: 'vote', id: this.statementId}, function() {
            this.voteNode.addClassName('hidden');
            this.unvoteNode.removeClassName('hidden');
            this.andYouNode.removeClassName('hidden');
        }.bind(this));
    },
    
    _onUnvoteClick: function() {
        if (this.disabled) {
        	return;
        }
        this._query({action: 'unvote', id: this.statementId}, function() {
        	if (this.personal) {
            	this.node.addClassName('hidden');
            	this._onUnvotedPersonal(this);
        	} else {
	            this.unvoteNode.addClassName('hidden');
	            this.voteNode.removeClassName('hidden');
	            this.andYouNode.addClassName('hidden');
        	}
        }.bind(this));
    },
    
    _onUnvotedPersonal: function(statement) {
      // subscribe to this function  
    },
    
    _makeDisabled: function() {
    	[this.approveNode, this.denyNode].each(function(e) { if (e) {e.addClassName('disabled'); }});
    	this.disabled = true;
    },
    
    _makeEnabled: function(a, b) {
    	[this.approveNode, this.denyNode].each(function(e) { if (e) { e.removeClassName('disabled'); }});
    	this.disabled = false;
    },
    
    _onApproveClick: function() {
    	if (this.disabled) { return; }
    	this._query({action: 'approve', id: this.statementId}, this._onApprove.bind(this));
    },

    _onUnapproveClick: function() {
    	if (this.disabled) { return; }
    	this._query({action: 'unapprove', id: this.statementId}, this._onUnapprove.bind(this));
    },

    _onDenyClick: function() {
    	if (this.disabled) { return; }
    	
    	if (confirm(this.denyStatementMessage)) {
    		this._query({action: 'deny', id: this.statementId}, this._onDeny.bind(this));
    	}
    },
    
    _onPeopleClick: function() {
    	if (this.listNode) {
    		this.listNode.toggleClassName('hidden');
    	}
    	this.peopleButtonNode.hide();
    },
    
    _onApprove: function() {
    	this._makeEnabled();
    	this.approveNode.addClassName('hidden');
    	this.denyNode.addClassName('hidden');
    	this.unapproveNode.removeClassName('hidden');
    	this.node.removeClassName('statement_unconfirmed').addClassName('statement_confirmed');
		this._onApproveHook();
    },

    _onDeny: function() {
    	this._makeEnabled();
    	this.node.addClassName('hidden');
		this._onDenyHook();
    },
    
    _onUnapprove: function() {
    	this._makeEnabled();
    	this.denyNode.removeClassName('hidden');
        this.unapproveNode.addClassName('hidden');
        this.approveNode.removeClassName('hidden');
    	this.node.removeClassName('statement_confirmed').addClassName('statement_unconfirmed');
    	this._onUnapproveHook();
    },
    
    _onDenyHook: function() {
    },
    
    _onApproveHook: function() {
    },

    _onUnapproveHook: function() {
    },
    
	_onError: function(tr) {
		this.node.addClassName('hidden');
	},

	_query: function(params, succFunc) {
		var request = new JsHttpRequest();
	    request.onreadystatechange = (function() {
	    	if (request.readyState == 4) {
	    		if (request.status || (request.status >= 200 && request.status < 300)) {
		    		(succFunc.bind(this))(request);
		    	} else {
		    		this._onError(request);
		    	}
    		}
    	}).bind(this);
	    request.open('get', this.url, true);
	    request.send(params);
	}
    
});
;

/**** /js/moikrug/widget/profile/PendingInvitation.js ****/
Lang.module('moikrug.widget.profile.PendingInvitation');

moikrug.widget.profile.PendingInvitation = Lang.createClass(moikrug.Widget, {
    init: function(node, options) {
		this.loading = false;
		this.acceptUrl = options.acceptUrl;
		this.denyUrl = options.denyUrl;
		this.junkUrl = options.junkUrl;
        this.baseConstructor(node, options, 'pendingInvitation', 'profile.pendingInvitation');
    },
    
    parse: function() {
        this.inviteNode = this.node.down('.invitation_node');
        this.inviteAlsoNode = this.node.down('.invite_also_node');
        this.noticeNode = this.node.down('.notice_block');
    	this.acceptButton = this.node.down('.accept');
    	this.ignoreButton = this.node.down('.x_close');
    	this.rejectButton = this.node.down('.reject');
    	this.junkButton = this.node.down('.junk');
        return this;
    },
    
    // check a number of extra persons suggested for an invitation and close block if there are no one left
    update: function() {
        // if here is no disabled node (not closed inviteMe widget)
        if (!this.inviteAlsoNode.select('.person_block').find(function(node) {
        		return !node.hasClassName("disabled");
        	})) {
            // wrapping up
            Effect.SlideUp(this.node.id);
        }
    },
    
    bindEvents: function() {
    	if (this.acceptButton) {
    		this.acceptButton.observe('click', this._onAccept.bind(this));
    	}
    	if (this.rejectButton) {
    		this.rejectButton.observe('click', this._onDeny.bind(this));
    	}
    	if (this.ignoreButton) {
    		this.ignoreButton.observe('click', this._onDeny.bind(this));
    	}
    	if (this.junkButton) {
    		this.junkButton.observe('click', this._onJunk.bindAsEventListener(this));
    	}
    	
    	// subscribe to invited persons blocks -- if they are gone -- close widget
    	if (this.inviteAlsoNode) {
        	this.inviteAlsoNode.select('.person_block').each(
        	    (function(node){
        	        var widget = WidgetRegistry.get(node);
        	        JSEvent.observe(widget, 'BlockClose', this.update.bind(this));
        	    }).bind(this)
        	);
    	}
    	
        return this;
    },
    
    _onStartLoading: function() {
    	this.loading = true;
    	this.acceptButton.disabled = true;
    	this.rejectButton.disabled = true;
    	this.ignoreButton.disabled = true;
    },
    
    
    _onAccept: function() {
    	this._query(this.acceptUrl, true);
    	// start progress wheel
    	this._displayProgress();
    },

    _onDeny: function() {
    	this._query(this.denyUrl);
    	this._displayProgress();
    },
    
    _onJunk: function(e) {
    	e.stop();
    	this._query(this.junkUrl);
    	this._displayProgress();
    },
    
    _onComplete: function(request, showInviteAlso) {
        this.inviteNode.addClassName('hidden');
		if (this.inviteAlsoNode && showInviteAlso) {
		    this.inviteAlsoNode.removeClassName('hidden');
		} else if (request.responseJS && request.responseJS.text) {
			
			this.noticeNode.removeClassName('hidden');
			this.noticeNode.down('.pi_notice_content').innerHTML = request.responseJS.text;
		}
		// stop progress wheel
        this._hideProgress();
    },
    
    _onError: function() {
		this.node.hide();
		// stop progress wheel
        this._hideProgress();
	},
	
	_query: function(url, showInviteAlso) {
		if (this.loading) {
			return;
		}
		this._onStartLoading();
		var request = new JsHttpRequest();
	    request.onreadystatechange = (function() {
	    	if (request.readyState == 4) {
	    		if (request.status || (request.status >= 200 && request.status < 300)) {
		    		this._onComplete.bind(this)(request, showInviteAlso);
		    	} else {
		    		this._onError.bind(this)(request);
		    	}
    		}
    	}).bind(this);
	    request.open('get', url, true);
	    request.send(null);
	},
	
	_displayProgress: function() {
        this.inviteNode.style.backgroundImage = "url(/images/icon_updating.gif)";
	},
	
	_hideProgress: function() {
        this.inviteNode.style.backgroundImage = "";
	}
    
});
;

/**** /js/moikrug/widget/PersonGroup.js ****/
Lang.module('moikrug.widget.PersonGroup');
Lang.include('moikrug.Widget');

moikrug.widget.PersonGroup = Lang.createClass(moikrug.Widget, {
	init: function(node, options, name) {
		this.baseConstructor(node, options, 'Favorite', name);
		this.url = options.url;
		this.obj_id = options.obj_id;
		this.label_id = options.label_id;
	},
	
	parse: function() {
		this.delNode = this.node.down('.group_del');
		return this;
	},
	
	bindEvents: function() {
		this.delNode.observe('click', this._onDelClick.bindAsEventListener(this));
		this.delNode.observe('mouseover', this._onHover.bindAsEventListener(this));
		this.delNode.observe('mouseout', this._onHoverout.bindAsEventListener(this));
	},
	
	_onDelClick: function() {
		this._removeLabel();
	},
	
	_onHover: function() {
		this.delNode.removeClassName('transparent');	
	},
	
	_onHoverout: function() {
		this.delNode.addClassName('transparent');	
	},
	
	_removeLabel: function() {
		this.node.hide();
		this._query({
			action: 'remove',
			obj_id: this.obj_id,
			label_id: this.label_id
		}, function() {
			this.node.remove();					
		}, function() {
			this.node.show();
		});
		
	},
	
	_query: function(params, succFunc, errorFunc) {
		var request = new JsHttpRequest();
	    request.onreadystatechange = (function() {
	    	if (request.readyState == 4) {
	    		if (request.status || (request.status >= 200 && request.status < 300)) {
		    		(succFunc.bind(this))(request);
		    	} else {
		    		if (errorFunc) {
		    			(errorFunc.bind(this))(request);
		    		}
		    	}
    		}
    	}).bind(this);
	    request.open('get', this.url, true);
	    request.send(params);
	}
	
});
;

/**** /js/moikrug/widget/Label/Dropdown.js ****/
/**
 * @author ilazarev
 * @requires moikrug.Widget
 */
Lang.module('moikrug.widget.Label.Dropdown');
Lang.include('moikrug.Widget');

/**
 * @class moikrug.widget.Label.Dropdown
 */
moikrug.widget.Label.Dropdown = Lang.createClass(moikrug.Widget, {

	/**
	 * @param {Element} node
	 * @param {object} options
	 * @param {string} name
	 * @param {string} className
	 */
	init: function(node, options, name, className) {
		this.baseConstructor(node, options, name, className || 'Label.Dropdown');
		this.actions = {
			'label_action_add' : [],
			'default': []
		};
	},
	
	/**
	 * @return {moikrug.widget.Label.Dropdown}
	 */
	parse: function() {
		this.containerNode = this.node.up();
		return this;
	},
	
	/**
	 * @return {moikrug.widget.Label.Dropdown}
	 */
	bindEvents: function() {
		this.node.observe('change', this._onChange.bindAsEventListener(this));
		this.containerNode.observe('click', this._onContainerClicked.bindAsEventListener(this));
		this.node.observe('click', this._onNodeClicked.bindAsEventListener(this) );
		return this;
	},
	
	_onChange: function(e) {
		this.justChanged = true;
		var value = this.node.value;
		if (this.actions[value]) {
			// run action handler
			this.actions[value].each(function(h){ h(); });
		} else {
			// no custom handlers - submit form
			if (this.node.form) {
				this.submitHook();
				this.node.form.submit();
			}
		}
		
	},
	
	_onNodeClicked: function(e) {
		// some hack to separate events "click on control" and "change new value"
		if (this.justChanged) {
			e.stop();
			this.justChanged = false;
		}
	},
	
	_onContainerClicked: function(e) {
		this.clickHook();
	},
	
	clickHook: function() {
		
	},

	submitHook: function() {
		
	},
	
	addHandler: function(action, handler) {
		if (!this.actions[action]) {
			this.actions[action] = [];
		}
		this.actions[action].push(handler);
		
		return this;
	},
	
	resetSelection: function() {
		this.node.value = this.node.down().value;
	},
	
	setSelectionToAction: function(action) {
		if (this.actions[action]) {
			this.node.value = action;
		}
	},

	addPersonIdMark: function(objId) {
		var node = document.createElement('input');
		node.type = 'hidden';
		node.name = this.getWidgetName() + "_person_id[]";
		node.value = objId;
		this.node.appendChild(node);
	},
	
	disableBlock: function() {
		this.node.disabled = 'disabled';
	
	},
	
	enableBlock: function() {
		this.node.disabled = undefined;
	}
	
});

;

/**** /js/moikrug/widget/Label/Edit.js ****/
Lang.module('moikrug.widget.Label.Edit');

moikrug.widget.Label.Edit = Lang.createClass(moikrug.Widget, {
    init: function(node, options, name, className) {
        this.baseConstructor(node, options, name, className || 'label.Edit');
    },

    parse: function() {
        this.pickerNode = this.node.down('.color_picker');
        this.colorBuckets = this.node.select('.color_bucket');
        this.colorBucketHidden = $(this.getWidgetName() + '_picked_color');
        this.cancelNode = this.node.down('.cancel');
        this.errorsNode = this.node.down('.errors');
        this.submitNode = this.node.down('.submit');
        this.deleteNode = this.node.down('.delete');
        this.inputNode = this.node.down('.label_text_name');
        return this;

    },

    bindEvents: function() {
        this.colorBuckets.each(function(colorBucket) {
            colorBucket.observe('click', this._onColorChange.bindAsEventListener(this));
            colorBucket.observe('mouseover', this._toggleColorBucketHighlighting.bindAsEventListener(this, true));
            colorBucket.observe('mouseout', this._toggleColorBucketHighlighting.bindAsEventListener(this, false));
        }.bind(this));
        this.cancelNode.observe('click', this.onCancel.bindAsEventListener(this));

        /* hack for IE6 and old opera */
        this.submitNode.observe('click', function(e) {
            e.stop();
            this.onSubmit();
            this.node.submit();
        }.bind(this));

        /* hack for IE6 and old opera */
        if (this.deleteNode) {
                this.deleteNode.observe('click', function(e) {
                e.stop();
                this.onSubmit();
                var tnode = document.createElement('input');
                tnode.type = 'hidden';
                tnode.name = this.deleteNode.name;
                tnode.value = this.deleteNode.value;
                this.node.appendChild(tnode);
                this.node.submit();
            }.bind(this));
        }


        /*
         * hide block by click out of block
         */
        this.node.observe('click', function(e) {
            if (this.isVisible()) {
                e.stop();
            }
        }.bindAsEventListener(this));

        document.observe('click',function() {
            if (this.isVisible()) {
                this.onCancel();
            }
        }.bindAsEventListener(this));

        return this;
    },

    _toggleColorBucketHighlighting: function(event, toBeHighlighted) {
        var colorBucket = Event.element(event);
        if (!colorBucket.hasClassName("current")) {
            colorBucket[ toBeHighlighted ? "addClassName" : "removeClassName" ]("hover");
        }
    },

    onCancel: function() {
        this.hideBlock();
        /**
         *  some street magic here
         *  if errors happened and form was closed we need hide
         *  error messages
         */
        this.errorsNode.addClassName('hidden');
        this.cancelHook();
    },

    cancelHook: function() {

    },

    onSubmit: function() {
        this.submitNode.disabled = 'disabled';
        this.submitHook();
    },

    submitHook: function() {

    },

    setColor: function(color) {
        var uColor = color.toUpperCase(),
            currentColorBucket;

        this.colorBucketHidden.value = uColor;
        this.colorBuckets.invoke("removeClassName", "hover");
        this.colorBuckets.invoke("removeClassName", "current");
        currentColorBucket = this.colorBuckets.find(function(item){
            var bgColor = item.style.backgroundColor;
            //some browsers return background color as hex number while others prefer to send back rgb string
            var hexColor = (bgColor.indexOf("#") + 1) ? bgColor.toUpperCase() : common.TextUtils.rgbStringToHex(bgColor).toUpperCase();
            return hexColor == uColor;
        });

        if (!!currentColorBucket) {
            currentColorBucket.addClassName("hover current");
        }
    },

    _onColorChange: function(e) {
        this.setColor(e.element().getAttribute("color"));
    },

    isVisible: function() {
        return !this.node.hasClassName('hidden');
    },

    showBlock : function() {
        this.node.removeClassName('hidden');
        this.inputNode.focus();

    },

    hideBlock : function() {
        this.node.addClassName('hidden');
    },

    moveBlockUnderElement: function(element) {
        var node = this.node;
        node.absolutize();
        var offset = element.cumulativeOffset();
        var offsetLocal = node.getOffsetParent().cumulativeOffset();
        node.style.top = offset.top - offsetLocal.top + element.getHeight() + 2 + 'px';
        node.style.left = offset.left - offsetLocal.left + 15 + 'px';

    },

    addPersonIdMark: function(objId) {
        var node = document.createElement('input');
        node.type = 'hidden';
        node.name = this.getWidgetName() + "_person_id[]";
        node.value = objId;
        this.node.appendChild(node);
    }
});
;

/**** /js/moikrug/ui/messaging/RecipientsList.js ****/
Lang.module('moikrug.ui.messaging.RecipientsList');

Lang.include('moikrug.ui.GrowingInput');
Lang.include('moikrug.ui.messaging.PersonSuggest');

moikrug.ui.messaging.RecipientsList = Lang.createClass(Widget, {
    init: function(node, options) {
        this.baseConstructor(node, options);
        this.people = [];
        this.selectedPerson = null;
    },

    parse: function() {
        var person = this.node.down(".RecipientsList_person_dummy");
        person.down(".RecipientsList_name").innerHTML = "";
        person.removeClassName(".RecipientsList_person_dummy");
        this.personTemplate = $(person.cloneNode(true));
        this.personTemplate.removeClassName("hidden");
        person.remove();
        
        var people = this.node.select(".RecipientsList_person");
        for (var i=0,l=people.length;i<l;i++) {
            var _person = people[i];
            this._addEventsForPerson(_person);
            this.people.push(_person);
        }
        
        this.input = this.node.down(".RecipientsList_input");
        var suggest = new moikrug.ui.messaging.RecipientsList.MyPersonSuggest(this.input, {
            serverTarget: "messagerecipients",
            invitation: this.options.invitation,
            alignNode: this.node,
            validate: (function(dataItem) {
                var id = dataItem.id;
                for (var i = 0,l = this.people.length; i < l; i++) {
                    if (this.people[i].down("input").value == id) {
                        return false;
                    }
                }
                return true;
            }).bind(this)
        }, this.widgetName + "_person").parse().bindEvents();
        suggest._updateWidth();
        suggest.observe("itemSelected", this.addPerson.bind(this));
        suggest.observe("blur", (function() {
            this.input.value = "";
        }).bind(this));
        suggest.observe("focus", (function() {
            this._resetSelection();
        }).bind(this));
        this._wrap = this.node.down(".wrap");
        this._focus = this.node.down(".RecipientsList_focus"); 
        return this;
    },

    bindEvents: function() {
        Event.observe(this.node, "click", (function() {
            this._resetSelection();
            this.input.focus();
        }).bind(this));
        var event;
        if (Prototype.Browser.Gecko || Prototype.Browser.Opera) {
            event = "keypress";
        } else {
            event = "keydown";
        }
        Event.observe(this.node, event, this._onNodeKeyDown.bindAsEventListener(this));
        return this;
    },

    addPerson: function(listItem) {
        var name = listItem.title;
        var id = listItem.dic_id;

        var person = $(this.personTemplate.cloneNode(true));
        person.down(".RecipientsList_name").innerHTML = common.TextUtils.highlightFirstLetterInName(name);
        person.down("input").value = id;
        this._addEventsForPerson(person);
        
        this.people.push(person);
        this.node.insertBefore(person, this.input);
        this.input.value = "";
        this.input.focus();
    },
    
    _addEventsForPerson: function(person) {
        Event.observe(person, "click", (function(e) {
            Event.stop(e);
        }).bindAsEventListener(this, person));
        Event.observe(person.down(".RecipientsList_name"), "focus", (function(e, man) {
            this.selectPerson(man);
            Event.stop(e);
        }).bindAsEventListener(this, person));
        Event.observe(person.down(".RecipientsList_close"), "click", (function(e, man) {
            this.removePerson(man);
            Event.stop(e);
        }).bindAsEventListener(this, person));
    },

    removePerson: function(person) {
        this.people = this.people.without(person);
        if (person == this.selectedPerson) {
            this.selectedPerson = null;
        }
        person.remove();
    },

    _onLeftKey: function(e) {
        var el = e.element();
        if (el == this.input && this.input.value !== "") {
            return;
        }
        this._selectPrevPerson();
    },

    _onRightKey: function(e) {
        var el = e.element();
        if (el == this.input && this.input.value !== "") {
            return;
        }
        var selected = this.selectedPerson;
        this._selectNextPerson();
        if (this.selectedPerson == selected) {
            this._resetSelection();
            this.input.focus();
            e.stop();
        }
    },

    _onBackspaceKey: function(e) {
        var el = e.element();
        if (el == this.input && this.input.value !== "") {
            return;
        }
        if (this.selectedPerson) {
            var prev = this._getPrevPerson();
            if (!prev) {
                prev = this._getNextPerson();
            }
            this.removePerson(this.selectedPerson);
            if (prev) {
                this.selectPerson(prev);
            } else {
                this.input.focus();
            }
        } else {
            this._selectPrevPerson();
        }
        e.stop();
    },

    _onDeleteKey: function(e) {
        var el = e.element();
        if (el == this.input && this.input.value !== "") {
            return;
        }
        if (this.selectedPerson) {
            var next = this._getNextPerson();
            if (!next) {
                next = this._getPrevPerson();
            }
            this.removePerson(this.selectedPerson);
            if (next) {
                this.selectPerson(next);
            } else {
                this.input.focus();
            }
        } else {
            this._selectPrevPerson();
        }
        e.stop();
    },

    _onNodeKeyDown: function(e) {
        switch (e.keyCode) {
            case Event.KEY_LEFT:
                this._onLeftKey(e);
                break;
            case Event.KEY_RIGHT:
                this._onRightKey(e);
                break;
            case Event.KEY_BACKSPACE:
                this._onBackspaceKey(e);
                break;
            case Event.KEY_DELETE:
                this._onDeleteKey(e);
                break;
        }
    },

    _resetSelection: function() {
        this.selectedPerson = null;
        this.node.select(".RecipientsList_person").each(function(person) {
            person.removeClassName("RecipientsList_person-selected");
        });
    },

    _getNextPerson: function(person) {
        person = person || this.selectedPerson;
        var index = this.people.indexOf(person);
        if (index == -1 || index == this.people.size() - 1) {
        	return null;
        }
        return this.people[index + 1];
    },

    _getPrevPerson: function(person) {
        person = person || this.selectedPerson;
        var index = this.people.indexOf(person);
        if (index <= 0) {
        	return null;
        }
        return this.people[index - 1];
    },

    _selectPrevPerson: function() {
        if (!this.selectedPerson) {
            if (this.people.size() > 0) {
                this.input.blur();
                this.selectPerson(this.people.last());
            }
            return;
        }
        var prev = this._getPrevPerson();
        if (prev !== null) {
            this.selectPerson(prev);
        }
    },

    _selectNextPerson: function() {
        if (!this.selectedPerson) {
        	return;
        }
        var next = this._getNextPerson();
        if (next !== null) {
            this.selectPerson(next);
        }
    },

    selectPerson: function(person) {
        this._resetSelection();
        this.selectedPerson = person;
        person.addClassName("RecipientsList_person-selected");
        this._focus.focus();
    },
    
    setFocus: function() {
        this.input.focus();
    }
    
});

moikrug.ui.messaging.RecipientsList.MyPersonSuggest = Lang.createClass(
    [moikrug.ui.messaging.PersonSuggest, moikrug.ui.GrowingInput], {

    init: function(node, options, name, className) {
        this.baseConstructor(node, options, name, className);
        this.alignNode = options.alignNode || this.node;
    },

    parse: function() {
        moikrug.ui.messaging.PersonSuggest.prototype.parse.apply(this);
        moikrug.ui.GrowingInput.prototype.parse.apply(this);
        return this;
    },

    bindEvents: function() {
        moikrug.ui.messaging.PersonSuggest.prototype.bindEvents.apply(this);
        moikrug.ui.GrowingInput.prototype.bindEvents.apply(this);
        return this;
    },

    updateListWidth: function() {
        if (this.alignNode.offsetWidth) {
            var newWidth = this.alignNode.offsetWidth - 2 + 'px';
            this.list.style.width = newWidth;
        }
    },

    updateListPosition: function() {
        var offset = this.alignNode.cumulativeOffset();
        this.list.style.left = offset[0] + "px";
        this.list.style.top = offset[1] + this.alignNode.offsetHeight - 1 + "px";
    },
    
    updateIndicatorPosition: function() {
        var offset = Position.cumulativeOffset(this.alignNode);
        this.indicator.style.left = offset[0] + this.alignNode.offsetWidth + 4 + 'px';
        this.indicator.style.top = offset[1] + 'px';
    },

    _updateText: function(text) {
        return text + "mm";
    }
});
;

/**** /js/moikrug/ui/StatementAddForm.js ****/
Lang.module('moikrug.ui.StatementAddForm');

moikrug.ui.StatementAddForm = Lang.createClass(Widget, {
    init: function(node, options) {
		this.maxlength = options.maxlength || 140;
        this.baseConstructor(node, options);
    },
    
    parse: function() {
        this.textInput = this.node.down('.message_message');
        this.hideControl = this.node.down(".statement_add_form_hide");
        this.submitButton = this.node.down(".statement_submit_btn");
        this.errorMsg = this.node.down(".length_error");
        return this;
    },
    
    showForm: function() {
        this.node.removeClassName("hidden");
    },
    
    hideForm: function() {
        this.node.addClassName("hidden");
        this.onHideForm();
    },
    
    onHideForm: function() {
    	//for subscription
    },
    
    toggleSubmit: function () {
    	if (this.textInput.value.length > this.maxlength) {
    		this.submitButton.disabled = true;
    		this.errorMsg.removeClassName("hidden");
    	} else {
    		this.errorMsg.addClassName("hidden");
    		this.submitButton.disabled = false;
    	}
    },

    bindEvents: function() {
    	var f = this.toggleSubmit.bind(this);
    	if (this.textInput) {
    		this.textInput.observe('keyup', f).observe('keydown', f);
    	}
    	if (this.hideControl) {
    		this.hideControl.observe('click', this.hideForm.bind(this));
    	}
        return this;
    }
});

;

/**** /js/moikrug/ChatNotificationManager.js ****/
Lang.module("moikrug.ChatNofiticationManager");

moikrug.ChatNotificationManager = Lang.createClass(Widget, {

	frameSize: null,
	msgCount: null,
	widgets: [],
	queen: null,
	msgContainer: null,

	closeNode: null,
	CLOSE_COOKIE: 'ChatNotificationManager_closed',

    init: function(node, options, limit, count) {
        this.baseConstructor(node, options);
        this.frameSize = limit;
        this.msgCount = count;
    },

    parse: function() {
        this.widgets = [];
        
        // Save sample (prototype) node and remove it from the container.
        this.queen = WidgetRegistry.get(this.node.down('.chat_notifier_item.hidden'));
        this.msgContainer = this.queen.node.parentNode;
        this.msgContainer.removeChild(this.queen.node);
        
        this.node.select('.chat_notifier_item').each((function(item) {
            this.widgets.push(WidgetRegistry.get(item));
        }).bind(this));
        
        this.closeNode = this.node.down('.chat_notifier_close');
        if (!this.isClosed()) {
        	this.setClosed(false);
        }

        this.limitFrame();
        return this;
    },

    bindEvents: function() {
        var markReadAndMaybeHide = (function(notification) {
            moikrug.Multiplexor.removeKey("Message", notification.getMessageId());
        }).bind(this);

        this.widgets.each((function(notification) {
            notification.observe("textClick", markReadAndMaybeHide.curry(notification));
        }).bind(this));
        
        Event.observe(this.closeNode, "click", (function(e) {
            e.stop();
            this.setClosed(true);
        }).bindAsEventListener(this));

        moikrug.Multiplexor.subscribe("Message", (function(messageData) {
            if (moikrug.ThreadPage && moikrug.ThreadPage.instance.threadId == messageData.threadId) {
                moikrug.Multiplexor.removeKey("Message", messageData.messageId);
                return;
            }
            var newNotification = this.queen.cloneCurrent();
            if (this.msgContainer.firstChild) {
		        this.msgContainer.insertBefore(newNotification.node, this.msgContainer.firstChild);
            } else {
		        this.msgContainer.appendChild(newNotification.node);
            }
            newNotification.setMessageId(messageData.messageId);
            newNotification.setPersonName(messageData.personName, messageData.personNameFull);
            newNotification.setPersonLink(messageData.personLink);
            newNotification.setMessageText(messageData.inlineText);
            newNotification.setMessageLink(messageData.url);
            newNotification.node.removeClassName("hidden");

            newNotification.observe("close", markReadAndMaybeHide.curry(newNotification));
            newNotification.observe("textClick", markReadAndMaybeHide.curry(newNotification));
            this.widgets.push(newNotification);
            this.msgCount++;
            this.limitFrame();

            this.setClosed(false);
            newNotification.blink();
            moikrug.TitleNotification.startBlink(messageData.personName + ' - ' + DIC.new_message_from);
            
        }).bind(this));
        return this;
    },
    
    limitFrame: function() {
		var f = $(this.msgContainer.parentNode).select('.chat_notifier_f')[0];
		var items = $(this.msgContainer).select('.chat_notifier_item');
		var nShown = 0;
		for (var i = 0; i < items.length; i++) {
			var item = items[i];
			var widget = WidgetRegistry.get(item);
			if (nShown < this.frameSize) {
	        	item.removeClassName("hidden");
				nShown++;
			} else {
	        	item.addClassName("hidden");
			}
        }
        if (this.msgCount <= nShown) {
        	f.style.display = 'none';
        } else {
        	f.style.display = '';
			$(f).select('a')[0].innerHTML = common.TextUtils.formatNumberTemplate(
				this.msgCount - nShown,
				DIC.chat_notifier_n_new_messages
			);
        }
    },
    
    setClosed: function(flag) {
        Cookie.set(this.CLOSE_COOKIE, flag? 1 : 0, null, "/");
        var allHidden = this.widgets.all(function(widget) {return widget.node.hasClassName("hidden");});
        if (!flag && !allHidden) {
        	this.node.removeClassName("hidden");
        } else {
        	this.node.addClassName("hidden");
        }
    },
    
    isClosed: function() {
        return parseInt(Cookie.get(this.CLOSE_COOKIE), 10);
    }
});
;

/**** /js/moikrug/TitleNotification.js ****/
Lang.module("moikrug.TitleNotification");

moikrug.TitleNotification = {

    focusStatus: false,
    blinkStatus: false,
    oldTitle: false,
    timeout: null,
    
    bindEvents: function() {
        if (Prototype.Browser.IE) {
            document.observe('focusin', this._setFocus.bindAsEventListener(this));
            document.observe('focusout', this._clearFocus.bindAsEventListener(this));
        } else {
	        document.observe('focus', this._setFocus.bindAsEventListener(this));
	        document.observe('blur', this._clearFocus.bindAsEventListener(this));
        }
        return this;
    },
    
    _setFocus: function() {
        this.focusStatus = true;
    },
    
    _clearFocus: function() {
        this.focusStatus = false;
    },
    
    startBlink: function(msg) {
        this.oldTitle = document.title;
        msg = msg.stripTags();
        msg = msg.replace(/\&.*?;/,'');
        this._blinkTitle(msg);
    },
    
    stopBlink: function() {
        this._clearFocus();
    },
    
    _blinkTitle: function(msg) {
        
        if (this.blinkStatus) {
            document.title = msg;
        } else {
            document.title = this.oldTitle;
        }
        this.blinkStatus = !this.blinkStatus;
        if (!this.focusStatus) {
            this.timeout = setTimeout(function() { this._blinkTitle(msg); }.bind(this), 1500);
        } else {
            document.title = this.oldTitle;
        }
        
    }
    
};
moikrug.TitleNotification.bindEvents();

;

/**** /js/moikrug/ui/messaging/ChatNotification.js ****/
Lang.module('moikrug.ui.messaging.ChatNotification');

Lang.include('moikrug.widget.Clonable');

moikrug.ui.messaging.ChatNotification = Lang.createClass(moikrug.widget.Clonable, {
    init: function(node, options, name, className) {
        this.baseConstructor(node, options, name, className || "ChatNotification");
    },

    _createClonedWidget: function(node, options, name, className) {
        return new moikrug.ui.messaging.ChatNotification(node, options, name, className).parse().bindEvents();
    },
    
    parse: function() {
        this.personNameNode = this.node.down(".chat_notifier_person");
        this.messageTextNode = this.node.down(".chat_notifier_text");
        return this;
    },
    
    bindEvents: function() {
        Event.observe(this.node, "click", (function() {
            this.onTextClick();
        }).bind(this));
        return this;
    },

    blink: function() {
        var node = this.node;
        var delay = 400;
        node.addClassName("chat_notifier_item_dark");
        window.setTimeout(function() {node.removeClassName("chat_notifier_item_dark");}, delay);
        window.setTimeout(function() {node.addClassName("chat_notifier_item_dark");}, delay*2);
        window.setTimeout(function() {node.removeClassName("chat_notifier_item_dark");}, delay*3);
        window.setTimeout(function() {node.addClassName("chat_notifier_item_dark");}, delay*4);
        window.setTimeout(function() {node.removeClassName("chat_notifier_item_dark");}, delay*5);
        window.setTimeout(function() {node.addClassName("chat_notifier_item_dark");}, delay*6);
        window.setTimeout(function() {node.removeClassName("chat_notifier_item_dark");}, delay*7);
    },

    close: function() {
        this.node.addClassName("hidden");
    },

    getMessageId: function() {
        return this.options.messageId;
    },

    setMessageId: function(id) {
        this.options.messageId = id; 
    },

    /**
     * Setters
     */
    setPersonName: function(name, fullName) {
        this.personNameNode.title = fullName;
        this.personNameNode.innerHTML = common.TextUtils.highlightFirstLetterInName(name);
    },

    setPersonLink: function(link) {
        // No separated link for a person. 
        //this.personNameNode.href = link;
    },

    setMessageLink: function(link) {
    	// Note that yo CANNOT do up('a'), because this.messageTextNode
    	// is not in DOMDocument yet at this time. :-(
    	node = $(this.messageTextNode).up(); 
        node.href = link;
    },

    setMessageText: function(text) {
        this.messageTextNode.down("span").innerHTML = text;
    },

    /**
     * Events
     */
    onClose: function(){},
    onTextClick: function(){}

});
;

/**** /js/moikrug/utils/ResourceLoader.js ****/
Lang.ModuleManager.module('moikrug.utils.ResourceLoader');

moikrug.utils.ResourceLoader = function(){
	
    var requests = {},										// hash to manage multiple requests
    	index = 0,											// request index used to generate unique id
    	head = document.getElementsByTagName("head")[0];	// head element resources will be appended to
    	
    /**
     * @param {Object} config Request config
     * @return {String} Identifier of placed request
     */
    var placeRequest = function(config) {
    	
    	var filesToBeLoaded = [];
    	
    	if (config.js) {
    		for ( i = 0; i < config.js.length; i++ ) {
    			filesToBeLoaded.push({
    				type : "js",
    				url  : config.js[i]
    			});
    		}
    	}
    	
    	if (config.css) {
    		for ( i = 0; i < config.css.length; i++ ) {
    			filesToBeLoaded.push({
    				type : "css",
    				url  : config.css[i]
    			});
    		}
    	}
    	
    	var requestID = getRequestID();
    	
    	var request = {
    		id : requestID,
    		isCompleted : false,
    		isAborted : false,
    		files : filesToBeLoaded,
    		onSuccess : config.onSuccess || null,
    		onFileLoad :config.onFileLoad || null
    	};
    	
    	requests[requestID] = request;
    	loadNext(requestID);
    	
    	return requestID;
    };
    
    /**
     * Returns unique identifier of requst
     * @retun {String} ID of request
     */
    var getRequestID = function() {
    	return "request_" + index++;
    };
    
    /*
     * Loads next resource file
     * @param {Number} id Request ID
     */
    var loadNext = function(id) {
    	if (requests[id]) {
    		var req = requests[id];
    		
    		if (req.isCompleted || req.isAborted) { return; }
    		
    		if (!req.files.length) {
    			if (typeof req.onSuccess === 'function') {
    				req.onSuccess();
    			}
    			moikrug.utils.Logger.log('Request "' + req.id + '" is completed');
    			req.isCompleted = true;
    			return;
    		}
    		
    		var fileToBeLoaded = req.files.shift();
    		if (fileToBeLoaded.type == 'css') {
    			loadCSS(fileToBeLoaded.url, req);
    		} else {
    			loadJS(fileToBeLoaded.url, req);
    		}
    	}
    };
    
    /**
     * Loads JavaScript file
     * 
     * @param {String} src File URL
     * @param {Object} request Request object created by placeRequest() method
     * @see placeRequest
     */
    var loadJS = function(src, request) {
    	if (!isFileLoaded('js', src)) {
    		var script = document.createElement('script');
    		script.setAttribute('type',"text/javascript");
            script.setAttribute('src', src);
            
            var isScriptLoaded = false;
            
            var onScriptLoad= function() {
        	    isScriptLoaded = true;
        		if (typeof request.onFileLoad === 'function') {
        			request.onFileLoad();
        		}
        		moikrug.utils.Logger.log('JavaScript File (' + src + ') is loaded');
        		loadNext(request.id);
            };
            
            // IE doesn't support onload event for script
            script.onreadystatechange = function() {
            	if (!isScriptLoaded && ("loaded" === script.readyState || "complete" === script.readyState)) {
            		// to prevent memory leak in IE
            		script.onreadystatechange = null;
            		onScriptLoad();
            	}
            };
            
            script.onload = onScriptLoad;
            
            head.appendChild(script);
    	} else {
    		loadNext(request.id);
    	}
    };
    
	 /**
	 * Loads CSS file
	 * 
	 * @param {String} src File URL
	 * @param {Object} request Request object created by placeRequest() method
	 * @see placeRequest
	 */
    var loadCSS = function(src, request) {
    	if (!isFileLoaded('css', src)) {
			var link = document.createElement('link');
			link.setAttribute('type', 'text/css');
			link.setAttribute('rel', 'stylesheet');
			link.setAttribute('media', 'all');
			link.setAttribute('href', src);
			
			var onCSSLoad = function() {
				if (typeof request.onFileLoad === 'function') {
			    	request.onFileLoad();
	    		}
	    		moikrug.utils.Logger.log('CSS File (' + src + ') is loaded');
	    		loadNext(request.id);
			};
			
			link.onload = onCSSLoad;
			
			head.appendChild(link);
			
			//Unfortunately it's possible to track loading status of CSS file in Opera and IE only
			if (!Prototype.Browser.IE && !Prototype.Browser.Opera) {
				onCSSLoad();
			}
	    } else {
	    	loadNext(request.id);
	    }
    };
    
   	/**
   	 * Whether or not file is already loaded
   	 * 
   	 * @param {String} fileType Possible values: 'css', 'js'
   	 */
    var isFileLoaded = function(fileType, src) {
		var isLoaded = false;
		
    	if (fileType == 'css') {
    		isLoaded = ($$('link[href*="' + src +'"]').length > 0);
    		if (isLoaded) {
    			moikrug.utils.Logger.log('CSS File (' + src + ') is already loaded');
    		}
    	} else if (fileType == 'js') {
    		isLoaded = ($$('script[src*="' + src +'"]').length > 0);
    		if (isLoaded) {
    			moikrug.utils.Logger.log('JavaScript File (' + src + ') is already loaded');
    		}
    	}
    	
    	return isLoaded;
    };
    
	//Public methods
	return {
		
		/**
		 * Loads static files (css, js) without blocking page.
		 * 
		 * @param {Object} config Request config object
		 * 
		 * Config properties:
		 * 	@param {Array} 	   css 			- Array containing urls of css files to be loaded
		 * 	@param {Array} 	   js  			- Array containing urls of js files to be loaded
		 *  @param {Function}  onSuccess 	- function to be invoked as all files are loaded
		 *  @param {Function}  onFileLoad	- function to be invoked after loading of each file
		 * 
		 * @return {Number} Identifier of request
		 */
		load : function(config){
			return placeRequest(config);
		},
		
		/**
		 * Aborts a request
		 * @param {String} Identifier of request to be aborted
		 */
		abort : function(id) {
			if (requests[id]) {
				requests[id].isAborted = true;
				moikrug.utils.Logger.log('Request "' + id + '" has been aborted');
			}
		}
	};
}();
;

/**** /js/moikrug/widget/AjaxLoader.js ****/
Lang.module('moikrug.widget.AjaxLoader');

moikrug.widget.AjaxLoader = Lang.createClass(moikrug.Widget, {
	init: function(node, options, name, className) {
    	this.baseConstructor(node, options, name, className);
	},

	parse: function() {
		if (this.options.isAutoload) {
		  this.load();
		}
		this.documentContainer = Element.extend(document.createElement('div'));
		this.node.appendChild(this.documentContainer);
		return this;
	},

    addContent : function(data) {
		this.documentContainer.update(data);
		this._bindSubmit(this.documentContainer);
	},
    
    _bindSubmit: function(container) {
    	var form = this.documentContainer.down('form');
    	if (!form) {
    		return; 
    	}
    	Event.observe(form, 'submit', function(e) {
    		e.stop();
    		this.submit(form);
    	}.bind(this));
    },
    
    addMedia : function(data, callback) {
    	var cssFilesURLs = [];
    	var jsFilesURLs = [];
    	var protocol = window.location.protocol;
    	
    	if(data.css) {
    		for (i = 0; i < data.css.length; i++) {
    			cssFilesURLs[i] = data.css[i];
    		}
    	}
    	
    	if(data.js) {
    		for (i = 0; i < data.js.length; i++) {
    			jsFilesURLs[i] = protocol + data.js[i];
    		}
    	}
    	
		moikrug.utils.ResourceLoader.load({
			css : cssFilesURLs,
			js : jsFilesURLs,
			onSuccess : callback
		});
    },
    
    submit: function(form)
    {
    	
    	var data = form.serialize({hash : true});
    	var idx = 0;
    	for (idx in data) {
    			
    		if (idx.match(/\[\]/) && typeof data[idx] == 'object') {
    			var value = data[idx];
    			delete data[idx];
    			data[idx.substr(0, idx.length - 2)] = value;
    		}
    	}
    	this._query(data, 'post');
    },
    
    clean: function ()
    {
    	this.documentContainer.descendants().each(function(item){
			item.remove();
    	});
    },
    
    load: function () 
    {
    	this._query();
    },
    
    
    _query: function(data, method)
	{	    	    
	    var request = new JsHttpRequest();
	    var manager = moikrug.widget.AjaxLoader.MediaManager;
	    
	    if (!method) {
	    	method = this.options.hasOwnProperty("method") ? this.options.method : "get";
	    }
	    
	    var dataToSend = $H({
            'imported_blocks': window['imported_blocks']
        });
	    dataToSend = dataToSend.merge(this.options.data);
	    if (data) {
	    	dataToSend = dataToSend.merge(data);
	    }
	    
	    request.onreadystatechange = (function() {
	        if (request.readyState == 4) {
	            if (request.status || (request.status >= 200 && request.status < 300)) {
	            	var mediaContent = request.responseJS.required_jscss;
	            	var htmlContent = request.responseJS.html;
	            	var widgetType = request.responseJS.widget_type;
	    			   
	            	if (request.responseJS.status && request.responseJS.status == 302) {
						window.location = request.responseJS.url;
						return;
					}
	            	
	            	var addHTMLContent = function() {
	            		this.addContent(htmlContent);
	            		this.node.fire('content:loaded');
	            	}.bind(this);
	            	
	            	if (!manager.isMediaLoaded(widgetType)) {
	            		this.addMedia(mediaContent, function(){
	            			addHTMLContent();
	            			manager.registerWidget(request.responseJS.widget_type);
	            		});
	            	} else {
						addHTMLContent();
	            	}
	            }
	        }
	    }).bind(this);
	    
	    
	    request.loader = 'xml';
	    request.open(method, this.options.server_target, true);
	    request.send(dataToSend.toObject());
    }
});

moikrug.widget.AjaxLoader.MediaManager =  {

    typeRegistry : {},
    
    registerWidget: function(type) {
        this.typeRegistry[type] = true;
    },
    
    isMediaLoaded: function(type) {
        return this.typeRegistry[type];
    }
};
;

/**** /js/moikrug/widget/profile/AskToFill.js ****/
Lang.module('moikrug.widget.profile.AskToFill');

moikrug.widget.profile.AskToFill = Lang.createClass(moikrug.Widget, {
	init: function(node, options, name, className) {
		this.baseConstructor(node, options, name, className || 'profile.AskToFill');
	},
	
	bindEvents: function() {
		var button = this.node.down('input[type=submit]');
		button.observe('click', this._onButtonClick.bindAsEventListener(null, button, this.node.down('input[name=what]').value, this.node.down('input[name=personId]').value));
	},
	
	_onButtonClick: function(event, elt, what, personId) {
		Event.stop(event);
		JsHttpRequest.query(
	        'GET ' + window.location.protocol + '//' + window.location.host + '/widgets/ajax/askToFill',
			{
				what: what,
				id: personId
			},
			function (result, err) {
				if (err && window.console) {
					console.log(err);
				}
				if (!result) {
					return;
				}
				var div = document.createElement("p");
				div.innerHTML = result;
				div.className = 'atf_content';
				reg = elt.parentNode.parentNode;
				reg.parentNode.replaceChild(div, reg);
			}
		);
	}
	
});
;
