/*
* UI notificvation subsystem. Could be used at any place.
* By design user should use singleton object.
* getNsyghtNotification default interface method to get instance.
* push_new_notify - method to show some notifications to user.
* parametrs:
* String - Notification message.
*       or
*  options:
*       message: Notification message
*       timeout: how long message should be displayed
*       type: message type notify_message, error_message  
* */

NsyghtNotification = {
    nsyghtNotification: undefined,
    getNsyghtNotification: function()
    {
        if ( !this.nsyghtNotification )
            this.nsyghtNotification = new this.__NsyghtNotification();
        return this.nsyghtNotification;
    },
    __NsyghtNotification: function( options )
    {
        this.__init__( options );
    }
};

NsyghtNotification.__NsyghtNotification.prototype =
{
    __init__: function( options )
    {
        // TODO: we need hard_max elemnts on page predefined value... 

        // Element of the list
        // message: "string"
        // type: "css block"
        this.notifys_queue = [];
        this.html_queue = [];
        this.notify_area_id = "notify_area";
        this.semafor = 0;

        // indexes:
        // 1 - identification
        // 3 - class value
        // 5- notification body
        this.template = [
            '<div id="', '' ,'" class="', '' ,'">', '','</div>' ];

        this.default_notify_options = {
            type: "notify_message",
            timeout: 5 * 1000
        };

        this.HTML_ID_PREFIX = "nfy_";

        this.DEFAULT_CSS_CLASS = 'na_unit';
        // type 2 css class
        this.CSS_MAP = {
            'notify_message': 'na_unit',
            'error_message': 'na_unit na_unit_error'
        };

        // Max number notifys fro block.
        this.HARD_MAX_NOTIFYS = 3;

        // type rules
        this.URGENT_NOTIFYS = {
            'error_message': true
        };

        this.__update_object( this.default_notify_options, options );
    },
    __boundrayMethod: function( d_obj, method )
    {
        if ( !d_obj || !method )
            return false;
        return function()
        {
            return method.apply( d_obj, arguments );
        }
    },
    __update_object: function( to_object, from_object )
    {
        var i, val;
        if ( arguments.length < 2 ) return false;
        for (  i = 0; i < arguments.length; i++ )
            if (  arguments[i] == undefined )
                return false;

        for ( i in to_object )
        {
            val = from_object[i];
            if ( to_object[i] != undefined && val != undefined )
                to_object[i] = val;
        }
        return true;
    },
    __get_last_notify_elem: function()
    {
        var htmlid = this.html_queue.shift();
        var elems = $( "#" + htmlid );
        return elems.length != 0? elems[0]: undefined;
    },
    __get_notifys_count: function()
    {
        return $( "#" + this.notify_area_id ).find( "div.na_unit:last" ).length;
    },
    push_new_notify: function( param )
    {
        var options = {};
        var key;

        for ( key in this.default_notify_options )
            options[key] = this.default_notify_options[key];

        this.__update_object( options, param );
        if ( param.hasOwnProperty( 'timeout' ) )
            options.timeout = options.timeout * 1000;

        if ( typeof param["message"] == "string" )
            options["message"] = param["message"];
        else if ( typeof param  == "string" )
            options["message"] = param;

        if ( options["message"] == undefined ) return false;

        this.notifys_queue.push( options );

        this.show_notify_fromqueue();
    },
    show_notify_fromqueue: function()
    {
        if ( this.html_queue.length >= this.HARD_MAX_NOTIFYS ) return false;

        var last_notify = this.notifys_queue.length > 0?
                this.notifys_queue[this.notifys_queue.length - 1]: {'type': undefined};
        var is_urgent = this.URGENT_NOTIFYS.hasOwnProperty( last_notify.type );
        if ( this.semafor && !is_urgent ) return false;

        var notify = is_urgent? this.notifys_queue.pop(): this.notifys_queue.shift();
        var template = this.template.concat([]);
        var elem, content;
        var _this = this;
        var tmp;

        if ( notify == undefined ||
                $( "#" + this.notify_area_id ).length == 0 ) return false;

        tmp = this.CSS_MAP[ notify.type ];

        template[1] = this.HTML_ID_PREFIX + new Date().getTime().toString();
        template[3] = tmp? tmp: this.DEFAULT_CSS_CLASS;
        template[5] = notify.message;

        this.html_queue.push( template[1] );

        content = template.join( "" );
        $( "#" + this.notify_area_id ).prepend( content );
        $( "#" + template[1] ).fadeIn( 'slow' );
        this.semafor += 1;

        window.setTimeout( this.__boundrayMethod( _this, _this.remove_notify ), notify.timeout );
    },
    remove_notify: function()
    {
        var element = this.__get_last_notify_elem();
        if ( element )
        {
            $( element ).fadeOut( "slow" );
            $( element ).unbind();
            $( element ).find( "*" ).unbind();
            $( element ).remove();
        }
        this.semafor = this.__get_notifys_count();
        this.show_notify_fromqueue();
    }
};