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

moikrug.Sidebar = Lang.createClass(Widget, {
    init: function(node, options) {
        this.baseConstructor(node, options);
        this.cookieStr = Cookie.get('Sidebar#');
        if (!this.cookieStr) {
        	this.cookieStr = '';
        }
        this.date = new Date();
        this.date.setTime(this.date.getTime()+(365 * 24 * 60 * 60 * 1000 ));
    },
    
    bindEvents: function() {
  
        var re = new RegExp("." + this.node.id + ".");
        if (re.test(this.cookieStr)) {
            this.node.addClassName('closed');
        }
        Event.observe(this.node.firstDescendant(), "mousedown", this._toggle.bind(this));
        Event.observe(this.node.firstDescendant(), "click", this._toggle.bind(this));
        

    },
    
    _toggle: function(e) {
        e.stop();
        if (e.type == 'mousedown') {
            this.node.toggleClassName('closed');
            var str = "." + this.node.id + ".";
            var re = new RegExp(str);
            this.cookieStr = re.test(this.cookieStr) ? this.cookieStr.replace(re,'') : this.cookieStr + str;
            Cookie.set('Sidebar#', this.cookieStr, this.date);
        }
        return false;
    }
});
;

/**** /js/moikrug/ui/Lfj_selector.js ****/
moikrug.ui.Lfj_selector = function() {
    this.init = function() {
        this.parse();
        this.bindEvents();
    };

    this.parse = function() {
        this.active = $('active');
        this.passive = $('passive');
        this.selector = $('lfj_toggle');
        this.parent = $('lfj_status');
    };

    this.bindEvents = function() {
        Event.observe(this.active, 'mousedown', this.turn_on.bind(this));
        Event.observe(this.passive, 'mousedown', this.turn_off.bind(this));
        Event.observe(this.selector, 'mousedown', this.toggle.bind(this));
    };

    this.turn_on = function(e) {
        this.parent.removeClassName('passive');
        this.parent.addClassName('active');
        e.stopPropagation();
        e.preventDefault();
    };

    this.turn_off = function(e) {
        this.parent.removeClassName('active');
        this.parent.addClassName('passive');
        e.stopPropagation();
        e.preventDefault();
    };

    this.toggle = function(e) {
        this.parent.toggleClassName('active');
        this.parent.toggleClassName('passive');
        e.stopPropagation();
        e.preventDefault();
    };
};
;

/**** /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/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(){}

});
;
