
    function BxShoutBox()
    {
        this.oMessages = new Object(),
        
        // contain page's URL for queries;
        this.sPageReceiver = '',

        // will check new messages;
        this.iUpdateTime = 0,

        this.updateTimeNotifyHandler = '',

        // last message's Id;
        this.iLastMessageId = 0,

        this.sMessagesContainer = 'shoutbox_wrapper',

        this.sMessage = '',
        this.sWaitMessage = '',

        this.oInputField = '',
        this._bUpdateIsFinished = true,
        this._stopUpdate = false;

        /**
         * Send message internal function only!
         */
        this._sendMessage = function()
        {
            var _sRandom = Math.random();  
            var self = this;

            $.post(this.sPageReceiver + 'write_message' + '&_r=' + _sRandom, { 'message': this.sMessage }, function(sData){
            	self._stopUpdate = false;

            	if(!sData && self._bUpdateIsFinished == true) {
                   self.getMessages();
                }
                else {
                    alert(sData);
                }                        
            });

            this.oInputField.value = '';
        },

        /**
         * Start sleep procces
         */
        this._startSleepProcces = function()
        {
        	var _this = this;

        	if(this._bUpdateIsFinished == true) {
        		//content was updated
        		this._sendMessage();
        	}
        	else {
        		setTimeout(function(){
        			_this._startSleepProcces();
        		}, 1);
        	}
        },

        /**
         * Function will send message from logged member ;
         *
         * @param  : e (system event) ;
         * @param  : evElement (object) (link on current field);
         */
        this.sendMessage = function(e, evElement)
        {
            var self = this;

            if(!e) {
                if( window.event ) { //Internet Explorer
                  e = window.event;
                } 
                else { //total failure, we have no way of referencing the event
                  return;
                }
            }

            var n = e.keyCode ? e.keyCode : e.charCode; 

            if (n == 13) { //Enter
            	//check sent message status
            	if(this._stopUpdate == true) {
            		alert(this.sWaitMessage);
            		return;
            	}

                var sMessage = $.trim(evElement.value);
                // clear all tags;
                sMessage = sMessage.replace(/<\/?[^>]+>/gi, '');

                // send message
                if(sMessage) {
                	
                    // stop the deserted notify procces;
                    clearTimeout(this.updateTimeNotifyHandler);

                	//define message	
                	this.sMessage = sMessage;
                	this.oInputField = evElement;

                	this._stopUpdate = true;

                	//update not finished yet
                	if(this._bUpdateIsFinished == false) {
                		//start sleep procces
                		this._startSleepProcces();
                	}
                	else {
                		//send message
                		this._sendMessage();
                	}
                }
                else {
                    alert(this.oMessages.empty_message);
                    evElement.value = '';
                }
            }
        },

        /**
         * Function will return all latest messages list;
         *
         */
        this.getMessages = function()
        {
            var self = this;
            var _sRandom = Math.random();  
            this._bUpdateIsFinished = false;

            $.getJSON(this.sPageReceiver + 'get_messages/' + this.iLastMessageId + '&_r=' + _sRandom, function(data){
                self.iLastMessageId = parseInt(data.last_message_id);
                self._bUpdateIsFinished = true;

                if(data.messages){

                    var $el = $('.' + self.sMessagesContainer);
                    // need for scroll content;
                    var iOldContentHeight = self.getContentHeight($el);
                    var iChatBoxHeight    =  $el.outerHeight();
 
                    $el.append(data.messages);

                    var iNewContentHeight = self.getContentHeight($el);

                    // scroll content;
                    iOldContentHeight -= iChatBoxHeight;
                    if( iOldContentHeight <= $el.scrollTop() ) {
                        $el.scrollTop(iNewContentHeight)
                    }
                }

                // start update procces again;
                if(self._stopUpdate == false) {
	                self.updateTimeNotifyHandler = setTimeout(function(){
	                   self.getMessages(self.getMessages);
	                }, self.iUpdateTime);
                }
            });
        },

        /**
         * Function will get the chat box's sub content height;
         *
         * @param  : $oChatBox (object) - chat box;
         * @return : (integer) - sub content height;
         */
        this.getContentHeight = function($el)
        {
            var iHeight = 0;

            // define the chat boxe's childrens height;
            $el.children().each(function(){
                iHeight += $(this).outerHeight();
            });

            return iHeight;
        },

        /**
         * Function will scroll content to the end of container;
         */
        this.scrollContent = function($el)
        {
            // define container's height;
            if(typeof $el == 'undefined') {
                var $el = $('.' + this.sMessagesContainer);
            }

            $el.scrollTop( this.getContentHeight($el) );
        }
    }
