// Classes, constants to work with Nsyght Events.
// -----------------------------------------------
// -----------------------------------------------


$(document).ready(function() {
var eventTemplate = [
    '<li id="{id:s}" class="hidden clearfix">',
    '<div class="avatar"><a class="userbox_href hidden" href="{userboxHref:s}"/>',
    '<a href="{userLink:s}">',
    '<img id="avatar_{nid:s}" src="{avatar:s}" alt="avatar" onerror="error_avatar_load(\'{nid:s}\');" title="<img src="/media/img/spinner.gif" class="userbox"/>',
    // '<img class="gearbox" src="/media/images/gearbox.png">',
    '</a></div>',
    '<div class="comment_details"><p>',
    '<a class="username-color" href="{userLink:s}">{displayName:s}</a> ',
    '{verbIcon:s}',
    '{title:s}{alternateLink:s}</p>',
    '<div class="comment_meta"><a href="/actions/view/{nid:s}"><span class="time">{timeSince:s} {fromNetwork:s}</span></a> - {actions:s}</div>',
    '</div>',                         
    '<ul class="media clearfix">{embeds:s}</ul>',
    '</li>'];

var eventRadioTemplate = [
    '<li id="{id:s}" class="clearfix nsyght_radio">',
    '<div class="avatar"><a href="{userLink:s}">',
    '<img id="avatar_{nid:s}" src="{avatar:s}" alt="avatar" onerror="error_avatar_load(\'{nid:s}\');"/>',
    '</a></div>',
    '<div class="comment_details"><p>',
    '<a class="username-color" href="{userLink:s}">{displayName:s}</a> ',
    '{title:s}</p>',
    '</div>',
    '</li>'];


//add embed and tags
var mediaTemplate          = '<div class="embeds">{embed_items:s}</div><div class="clear"></div>';
var embedItemTemplate      = '<div class="embed_item">{embed_thumbnail:s}{embed_title:s}{embed_html:s}</div>';
var thumbnailTemplate      = ['<div class="floatLeft">',
                              '<div class="thumbsContainer">',
                              '<a href="{url:s}" class="no-embed">',
                              '<img style="max-width:400px;max-height:300px;" src="{thumbnail:s}" class="embed_thumbnail"/>',
                              '{klop:s}',
                              '</a>',
                              '</div>',
                              '</div>'];
var embedTitleTemplate     = ['<div class="container"><p>{media_title:s}</p>',
                             '{media_alt:s}',
                             '</div>'];
var embedHtmlTemplate      = '<div class="embed {hidden:s}">{embedCode:s}</div>';
var replyTemplate          = '<a class="reply-action" onclick="return false;" href="/actions/reply/{id:s}">'+ gettext("Comment") +'</a>';
var repliesTemplate        = '<a class="comment-link" href="{id:s}" onclick="return false;">({numReplies:s} '+ gettext("Comments") +')</a>';
var viewDiscussionTemplate = '<a class="conversation-action" href="/actions/view/{id:s}">'+ gettext("View Discussion") +'</a>';
var shareTemplate          = '<a class="share-action" onclick="return false;" href="/actions/share/{id:s}">'+ gettext("Share") +'</a>';
var sharesTemplate         = '<a class="share-link" href="/actions/view/{id:s}">('+ gettext("Shared by ") +' numShares:s})</a>';
var likeTemplate           = '<a class="like-action" onclick="return false;" href="{like_link:s}">{like_text:s}</a>';

$.tpl('eventTemplate', eventTemplate);
$.tpl('eventRadioTemplate', eventRadioTemplate);
$.tpl('replyTemplate', replyTemplate);
$.tpl('repliesTemplate', repliesTemplate);
$.tpl('viewDiscussionTemplate', viewDiscussionTemplate);
$.tpl('shareTemplate', shareTemplate);
$.tpl('sharesTemplate', sharesTemplate);
$.tpl('likeTemplate', likeTemplate);
$.tpl('mediaTemplate', mediaTemplate);
$.tpl('embedItemTemplate', embedItemTemplate);
$.tpl('embedTitleTemplate', embedTitleTemplate);
$.tpl('thumbnailTemplate', thumbnailTemplate);
$.tpl('embedHtmlTemplate', embedHtmlTemplate);
});

//
// TODO: Find a better way for global scope.
//
var QueueGlobalScope = {
    GLOBAL_EVENTS_IDS: {},
    IS_MAINQUEUE_LOCKED: false 
}

function remapLoadedEvents( jSelector ) //{{{1
{
    // Hack method to reorganise loaded events from templates
    // This method shuld not be used in future. Right after we will 
    // switch to load all events as json objects.
    // Input selector should point to list of li elements

    var tmpIdsLinker = new IdentificatorsLinker();

    $(jSelector).each( function( i, elem ){
        elem.id = tmpIdsLinker.linkNewId( elem.id );
    });
}
//1}}}

function IdentificatorsLinker( ids_prefix, ids_container ) //{{{1
{
    // Basic class to link hbase events Ids with html ids
    this.__init__( ids_prefix, ids_container );
}

IdentificatorsLinker.prototype = {
    __init__: function( ids_prefix, ids_container ) //{{{
        {
        if ( !ids_prefix )
            ids_prefix = 'id' + new Date().getTime().toString();
        this.ids_prefix = ids_prefix;
        this.records_counter = 0;
        this.ids_storage = QueueGlobalScope.GLOBAL_EVENTS_IDS;  // UiId: hbaseId
        if ( ids_container )
            this.ids_storage = ids_container;
        this.eventIds = {};
        for (var i in this.ids_storage) {
            this.eventIds[this.ids_storage[i]] = i;
        }
    },
    //}}}...__init__
    linkNewId: function( hbase_id ) //{{{
    {
        this.records_counter += 1;
        var new_UiId = this.ids_prefix + '__' + this.records_counter;
        this.ids_storage[ new_UiId ] = hbase_id;
        return new_UiId;
    },
    //}}}...linkNewId
    getHbaseId: function( uiId ) //{{{
    {
        return this.ids_storage[uiId];
    },
    getHtmlId: function( htmlId ) //{{{
    {
        // TODO: Refactor this method!!!
        // Change name and remove element if not found at HTML.

    	for ( var elem in this.ids_storage )
    	{
    		if(this.ids_storage[elem] == htmlId) {
    			
    			if( $('#'.elem)) return elem;
    		}
    	}
    		
        return false;
    },
    //}}}..getHbaseId
    deleteUiId: function( uiId ) //{{{
    {
        delete this.ids_storage.uiId;
    },
    //}}}...deleteUiId
    addEventId: function(eventId) {
      this.eventIds[eventId] = eventId;
    },
    existsEventId: function(eventId) {
      var exists = eventId in this.eventIds;
      if(exists) return true;
      try {
        if(this != QueueGlobalScope.mainQueue.getIdsLinker())
          return QueueGlobalScope.mainQueue.getIdsLinker().existsEventId(eventId);
        QueueGlobalScope.mainQueue.getIdsLinker().addEventId(eventId);
      }catch(err) {
      }
      return false;
    },
    getNewEvents: function(events) {
        var filteredEvents = [];
        for (i=0; i<events.length; i++) {
          var e = events[i];
          if(!(this.existsEventId(e.id) ||
            (e.dupOf && this.existsEventId(e.dupOf)))) {
            filteredEvents.push(e);
            this.eventIds[e.id] = e.id;
            try {
            if (e.dupOf) {
              this.eventIds[e.dupOf] = e.id;
            }
            } catch (err) {}
          }
        }
        return filteredEvents;
    }
};

//}}}

function EventQueue( placeTo, isLiveUpdate, channel ) //{{{1
{
   this.__init__( placeTo, isLiveUpdate, channel )
}

EventQueue.prototype = {    //{{{2
    __init__: function( placeTo, isLiveUpdate, channel ) //{{{3
    {
        this._queueIdentifier = new Date().getTime().toString();
        this.setChannel( channel );

        this._events = [];
        this._isLiveUpdate = isLiveUpdate;
        this._isPauseEvents = false;
        this._numPauseEvents = 0;
        this._placeTo = placeTo;
        this._placeToCount = placeTo;
        this.__windowInterval = undefined;
        this._baseInterval = 4000;
        this._constantInterval = 0;
        this._eventObjectsLinker = new IdentificatorsLinker();
        this._isComment = false;
        this.tplName = 'eventTemplate';
        this.__template_render = this.__default_render_event_template;
        this.__instanceRender = this.renderWithDInterval;

        if (SETTINGS && typeof(SETTINGS.EVENT_PER_PAGE) != "undefined") {
           this.max_events_in_block = SETTINGS.EVENT_PER_PAGE
        } else {
           this.max_events_in_block = 10;
        }
    }, //3}}}...__init__
    beforeDelete: function()
    {
        clearInterval( this.__windowInterval );
        delete this._eventObjectsLinker;
        delete this._events;
        this._isLiveUpdate = false;
        this._isPauseEvents = true;
        this.__instanceRender = false;
    },
    getChannel: function() // {{{3
    {
        return this._channel;
    }, //3}}}... getChannel
    setChannel: function( channel ) // {{{3
    {
        this._channel = channel ? channel : "all";
        var re_channel = /^\/topic\//;
        this._channel = this._channel.replace( re_channel, "" );
    }, // 3}}}... setChannel
    getIdsLinker: function() // {{{3
    {
        return this._eventObjectsLinker;
    }, // }}}...getIdsLinker
    setIdsLinker: function( idsLinkerInstance ) //{{{3
    {
        if ( idsLinkerInstance )
            this._eventObjectsLinker = idsLinkerInstance;
    }, //3}}}...setIdsLinker
    getInstanceRenderer: function() // {{{3
    { return this.__instanceRender },///3}}}
    setInstanceRenderer: function( rendererInstance )// {{{3
    {
        this.__instanceRender = rendererInstance;
    }, ///3}}}
    getEventsInQueue: function() //{{{3
    {
        return this._events.length;
    }, //3}}}
    setMaxEventsInBlock: function( num ) //{{{3
    {
        if ( typeof(num) != "undefined" )
            this.max_events_in_block = num;
    }, //3}}}
    setIsPauseEvents: function( value ) //{{{3
    {
        // toggle render event.
        if ( typeof(value) == 'undefined' )
            return false;
        if ( value )
        {
            this.pauseLiveUpdate();
            this._isPauseEvents = true;
        } else {
            this.startLiveUpdate();
            this._isPauseEvents = false;
            this._numPauseEvents = 0;
            return;
        }
        this._numPauseEvents = this._events.length;
    }, //3}}}
    getIsPauseEvents: function() //{{{3
    {
        return this._isPauseEvents
    }, //3}}}
    pauseRendererSwitcher: function() // {{{3
    {
        if ( this._isPauseEvents )
            this.setInstanceRenderer( this.renderNewEventsCounterAndTitle );
        else
            if ( this._isLiveUpdate )
                this.setInstanceRenderer( this.renderWithDInterval );
    },
    //3}}}
    setTplName: function( tplVal ) //{{{3
    {
        this.tplName = tplVal;
    }, //3}}}
    addEvents: function( eventsObjects ) //{{{3
    {
        // Add list of events to queue.
        // Prepear each event for processing.
        if ( ! eventsObjects && eventsObjects.length == 0)
            return false;
        
        var filteredEvents = this._eventObjectsLinker.getNewEvents(eventsObjects);
        this.addEventsUnchecked(filteredEvents);
    },//3}}}
    addEventsUnchecked: function(eventsObjects) {
        if ( ! eventsObjects && eventsObjects.length == 0)
            return false;
        if ( ! this._isPauseEvents )
            this._events = this._events.concat( eventsObjects );
        else
            this.__processPauseEvents( eventsObjects );
      
    },
    pushEvents: function( newEventsList, isRend )  //{{{3
    {
        var isCallRender = isRend != false;

        if ( !newEventsList ) return false;
        this.addEvents( newEventsList );
        if ( isCallRender ) this.callInstanceRenderer();
    }, //3}}}...pushEvents
    setIsComment: function( is_comment ) //{{{3
    {
        this._isComment = is_comment;
    },//3}}}
    loadsEvents: function( jsonEvents, isRend ) //{{{3
    {
        // Get event from JSON string. Add them to main queue
        // Start to output them with delay if needed.
        var new_events = [];
        var isCallRender = isRend != false;

        if ( ! jsonEvents ) return false;

        var tmpBuff = jsonEvents.body;
        if ( typeof(tmpBuff) == "undefined" ) tmpBuff = jsonEvents;

        try
        {
            new_events = JSON.parse( tmpBuff );
        }
        catch( e )
        {
            new_events = [];
        }

        this.addEvents( new_events );

//        if ( this._isLiveUpdate )
//            this.renderWithDInterval()
        if ( isCallRender ) this.callInstanceRenderer();
    },//3}}}...loadsEvents
    setPlaceTo: function( jselector ) //{{{3
    {
        // setter fro jQuery selector variable.
        if ( ! jselector )
            return false;
        this._placeTo = jselector;
    },//3}}}
    setPlaceToCount: function( jselector ) //{{{3
    {
        // setter fro jQuery selector variable.
        if ( ! jselector )
            return false;
        this._placeToCount = jselector;
    },//3}}}
    pauseLiveUpdate: function() //{{{3
    {
        this._isLiveUpdate = false;
        clearInterval( this.__windowInterval );
        this.setInstanceRenderer( undefined );
    },
    //3}}}
    startLiveUpdate: function() //{{{3
    {
        this._isLiveUpdate = true;
        this.renderWithDInterval();
    },
    //3}}}
    callInstanceRenderer: function() // {{{3
    {
        var instanceRender = this.__instanceRender;
        if ( instanceRender &&
                instanceRender instanceof Function )
            this.__instanceRender();
    }, // 3}}}... callInstanceRenderer
    renderNewEventsCounterAndTitle: function() // {{{3
    {
        var title = gettext( "Nsyght | Live Stream" );
        var newEventsLabel = "";

        if ( this._numPauseEvents > 0 )
        {
            newEventsLabel = "(" + this._numPauseEvents + " new)";
            title = newEventsLabel + " " + title;
            document.title = title;
        }

        if ( this._placeToCount )
            $( this._placeToCount ).html( newEventsLabel );
    }, // 3}}}... renderNewEventsCounterAndTitle
    renderNewEventsCounter: function() // {{{3
    {
        var newEventsLabel = this._numPauseEvents > 0 ?
                "(" + this._numPauseEvents + " new)" : "";
        
        $( this.placeTo ).html( newEventsLabel );
    }, // 3}}}... renderNewEventsCounterAndTitle
    renderEvent: function( jselector, is_post ) //{{{3
    {
        if ( ! this._events || ! this._events.length )
            return false;

        var placeTo = this._placeTo;
        if ( jselector )
            placeTo = jselector;

        var evnt = this._events.shift();
        var html_block = this.__render_event_template( evnt );
        if (is_post) {
            $( placeTo ).prepend( html_block );
        } else {
            $( placeTo ).after( '<div class="comment_details comment_slidedown"><ul>'+html_block+'</ul></div>' );
        }
        $( placeTo ).children("li:hidden:first").fadeIn( 1000 );
        var element_to_remove = $( placeTo).children("li:gt(" + (this.max_events_in_block - 1) + ")");
        this.remove_elements( element_to_remove );

        if ( typeof( show_popup ) != 'undefined' )
        {
            $(this._placeTo).find('.share-action').click( show_popup );
            $(this._placeTo).find('.reply-action').click( show_popup );
            $(this._placeTo).find('.like-action').click(likeSubmit);
        }

    },//...renderEvent
    renderAllEventsBottom: function(jselector) //{{{3
    {
        this.renderAllEvents(jselector, true);
    },//...3}}}
    renderAllEvents: function(is_post, remove) //{{{3
    {
        // Push all event from queue to placeTo location.
        // get event, place them, add JS events to rendered part.
        var events_len = this._events.length;
        var html_block = '';
        for ( var i = 0; i < events_len; i++ )
        {
            var evnt = this._events.shift();
            html_block += this.__render_event_template( evnt );
        }

        is_post = typeof(is_post) != 'undefined'? is_post: true;
        if (!is_post) {
            // TODO: DEPRECATED
            //$( this._placeTo ).after(  '<div class="comment_details comment_slidedown"><ul>' + html_block + '</ul></div>' );
            $( this._placeTo ).append( html_block ).find(">li").removeClass( "hidden" );
        } else {
            $( this._placeTo ).prepend( html_block );
        }

        $("li:hidden").removeClass( 'hide' );

        $(this._placeTo).find('.share-action').click( show_popup );
        $(this._placeTo).find('.reply-action').click( show_popup );
        $(this._placeTo).find('.like-action').click(likeSubmit);

        remove = typeof(remove) != 'undefined'? remove: true;
        if (remove) {
            var element_to_remove = $(this._placeTo).children("li:gt(" + (this.max_events_in_block - 1) + ")");
            this.remove_elements( element_to_remove );
        }

        $('.gearbox').hide();
        $('#userResults .eventClass').slice(0, events_len).each(function() {
            AjaxResults.bindUserBoxes($(this).find('.userbox'));
        });

        this._numPauseEvents = 0;
    },
    //3}}}...renderAllEvents
    renderEventAppend: function( jselector, is_reply ) //{{{3
    {
        var sacrifice = this._eventObjectsLinker.getHtmlId(jselector);

        if ( !sacrifice ) return;

        sacrifice = '#' + sacrifice;

        if ( $(sacrifice).children('.actions').hasClass('impasse') )
        {
            this.setIsComment(true);
            this.max_events_in_block = SETTINGS.COMMENT_PER_EVENT;
            this.renderAllEventsBottom( $(sacrifice).parent() );
            closePopup();

            $(sacrifice).children('.actions').after('<div id="yellowMessage" class="hidden"><p id="showResultsFrom">Your message has been sent</p></div>');
            $('#yellowMessage').fadeIn( 'slow' );
            window.setTimeout('$("#yellowMessage").fadeOut( "slow" );', 2000);
            window.setTimeout('$("#yellowMessage").remove();', 3000);

            return;
        }

        $(sacrifice).children('.actions').after('<div id="yellowMessage" class="hidden"><p id="showResultsFrom">Your message has been sent</p></div>');
        $('#yellowMessage').fadeIn( 'slow' );
        window.setTimeout('$("#yellowMessage").fadeOut( "slow" );', 2000);
        window.setTimeout('$("#yellowMessage").remove();', 3000);

        var linkClass = '';
        if (is_reply) {
            linkClass = '.comment-link';
        } else {
            linkClass = '.share-link';
        }
        var newLink = $(sacrifice).find(linkClass);

        if($(newLink).length > 0)
        {
            var oldCount = 0;
            if (is_reply) {
                oldCount = parseInt(newLink.text().substring(1));
            } else {
                oldCount = parseInt(newLink.text().substring(gettext('Shared by ').length));
            }
            if (oldCount == NaN) { oldCount = 0; }
            var newCount = 1 + oldCount;

            if (is_reply) {
                $(newLink).html('(' + newCount + ' ' + gettext('Comments') + ')');
            } else {
                $(newLink).html('(' + gettext('Shared by') + ' ' + newCount + ')');
            }

            if ( $(sacrifice).find('.thumbnail').length > 0 )
                    $(newLink).click();
        } else {
            if (is_reply) {
                var html = ' <a onclick="return false;" href="' + jselector + '" class="comment-link">(1 ' + gettext('Comment') + ')</a>';
                if( $(sacrifice).find('.conversation-action').length == 0 )
                    html += ' - <a class="conversation-action" href="/actions/view/' + jselector + '">'+ gettext('View Discussion') +'</a> ';

                $(sacrifice).find('.reply-action').after(html);

                $(sacrifice).find('.comment-link').click( function( evnt )
                {
                    evnt.preventDefault();
                    new EventCommentsArea( this );
                });
            } else {
                var html = ' <a onclick="return false;" href="' + jselector + '" class="share-link">(' + gettext('Shared by') + ' 1)</a>';
                $(sacrifice).find('.share-action').after(html);

                $(sacrifice).find('.share-link').click( function( evnt )
                {
                    evnt.preventDefault();
                    new EventCommentsArea( this );
                });
            }
        }
    },//3}}}...renderEventAppend
    renderWithDInterval: function() //{{{3
    {
        var delay;
        var jselector = this._placeTo;
        clearInterval( this.__windowInterval );

        if ( ! this._isLiveUpdate )
        {
            this.renderAllEvents( jselector );
            return;
        } else {
            this.renderEvent( jselector, true );
        }

        if ( ! this._isLiveUpdate || ! this.getEventsInQueue() )
            return;
        // Use dynamic or constant interval delay.
        if ( ! this._baseInterval && this._constantInterval )
        {
            delay = this._constantInterval;
        } else {
            delay = (this._baseInterval * 10) / this.getEventsInQueue();
            if ( ! delay || delay > this._baseInterval || delay == Infinity )
                this.delay = this._baseInterval;
        }

        var _this = this;
        var callback = function()
            {return _this.renderWithDInterval.apply( _this, arguments )};

        this.__windowInterval = window.setInterval( callback, delay );
    }, //3}}}
    setTemplateName: function( name ) //{{{3
    {
        if ( typeof( name ) == "undefined"  )
            return;
        this.tplName = name;
    }, //3}}}
    setTemplateRender: function( render ) //{{{3 
    {
        this.__template_render = render;
    }, ///}}}3
    __render_event_template: function() {//{{{3
        return this.__template_render.apply( this, arguments );
    }, //3}}} ... __render_event_template
    __default_render_event_template: function( evnt ) //{{{3
    {
        var tmp;
        var net = providers[evnt.providers[0]];
        var uiId = this._eventObjectsLinker.linkNewId( evnt.id );

        var title = this.__linkify_link(evnt.title);
        if (net.short_title == "twitter") {
            title = this.__linkify_tag(this.__linkify_user(title));
        }

        var actions = this.__buildNactionContent( evnt );
        var embeds = this.__buildEventEmbeds( evnt );

        var icon_net_title = net.short_title;
        if (evnt.fromNsyght && evnt.replyRoot == null) {
            icon_net_title = "nsyght";
        }

        var timeSince = evnt.timeSince + ' ' + gettext('ago');
        var fromNetwork = gettext('via') + ' ' + net.full_title;
        var alternateLink = '';
        if (evnt.alternateLink && evnt.alternateLink.length != 0) {
            alternateLink = '<a class="external_link" href="' + evnt.alternateLink + '"></a>';
        }
        var verbIcon = '';
        if (net.short_title == 'lastfm') {
            if (evnt.verb == 'loved') {
                verbIcon = '&hearts;&nbsp;';
            } else {
                verbIcon = '&#9835;&nbsp;';
            }
        }
        var userboxHref = '';
        if (evnt.isRegistered) {
            userboxHref = '/profile/userbox/' + evnt.user;
        } else {
            userboxHref = '/profile/userbox/' + net.short_title + '/' + evnt.serviceUser;
        }
        userboxHref += '/?current_url=' + window.location;

        tmp = $.tpl( this.tplName, {
            id:              uiId,
            nid:             evnt.id,
            title:           title,
            avatar:          evnt.avatar,
            verb:            evnt.verb,
            displayName:     evnt.displayName,
            userLink:        evnt.userLink,
            serviceLink:     evnt.serviceLink,
            alternateLink:   alternateLink,
            verbIcon:        verbIcon,
            userboxHref:     userboxHref,
            net_short_title: icon_net_title,
            timestamp:       evnt.timestamp,
            timeSince:       timeSince,
            fromNetwork:     fromNetwork,
            actions:         actions,
            embeds:          embeds
        }, true);
        return tmp;
    }, //3}}}... __default_render_event_template
    __buildNactionContent: function( evnt )
    {
        var tmp_actions = [];
        var tmp;
        var hasReplies;

        if ( evnt )
        {
            tmp = $.tpl('replyTemplate', {id:evnt.id}, true);
            tmp_actions.push( tmp );

            hasReplies = evnt.replies && evnt.replies.length > 0;
            if ( !this._isComment && hasReplies )
            {
                tmp = $.tpl( 'repliesTemplate',
                                {id:evnt.id, numReplies: evnt.replies.length},
                                true );
                tmp_actions.push( tmp );
            }
            if ( !this._isComment && (evnt.replyRoot || hasReplies) )
            {
                tmp = $.tpl('viewDiscussionTemplate', {id:evnt.replyRoot}, true);
                tmp_actions.push( tmp );
            }

            tmp = $.tpl('shareTemplate', {id:evnt.id}, true);
            tmp_actions.push( tmp );

            if ( evnt.numShares && evnt.numShares > 0 )
            {
                var shareId = evnt.shareOf ? evnt.shareOf : evnt.id;
                tmp = $.tpl('sharesTemplate', {id:shareId, numShares:evnt.numShares}, true);
                tmp_actions.push( tmp );
            }

            {
                var like_link = "/actions/" + (evnt.liked ? "/unlike/" : "/like/") + evnt.id;
                var like_text = evnt.liked ? gettext( "Unlike" ) : gettext("Like");

                tmp = $.tpl('likeTemplate', {like_text:like_text, like_link:like_link}, true);
                tmp_actions.push( tmp );
            }
        }
        return tmp_actions.join( " - " );
    },
    __buildEventEmbeds: function( evnt )
    {
        var embeds = '';
        var embedItems = '';
        var embedAltHtml = '';
        
        if ( evnt.embeds )
        {
            for ( var url in evnt.embeds )
            {
                var embedObj = evnt.embeds[url];
                var thumbnailHtml = '';
                var embedCodeHtml = '';
                var embedTitle = '';
                var hasThumbnail = false;

                if ( !embedObj ) continue;
                
                if ( embedObj.thumbnail )
                {
                    hasThumbnail = true;
                }
                if ( hasThumbnail )
                {
                    var klop = "";
                    if ( embedObj.embedType == 2 )
                        klop = "<span class=\"no-embed-klop\"></span>";
                    thumbnailHtml = $.tpl('thumbnailTemplate',
                                            {url: url,
                                             thumbnail: embedObj.thumbnail,
                                             klop: klop}, true);
                }
                if ( embedObj.embedCode )
                {
                    embedCodeHtml = $.tpl('embedHtmlTemplate',
                        {hidden: (hasThumbnail ? 'hidden' : ''),
                            embedCode: embedObj.embedCode}, true);
                }
                if (embedObj.title)
                {
                    embedAltHtml = embedObj.alt ? '<p>'+ embedObj.alt +'</p>' : '';
                    embedTitle = $.tpl('embedTitleTemplate',
                        { media_title: embedObj.title,
                            media_alt: embedAltHtml }, true);
                }
                embedItems += $.tpl('embedItemTemplate',
                    {embed_thumbnail: thumbnailHtml,
                        embed_title: embedTitle,
                        embed_html: embedCodeHtml}, true);
            }
        }

        if (embedItems.length > 0) {
            embeds = $.tpl('mediaTemplate', {embed_items: embedItems}, true);
        }

        return embeds;
    },
    getEventsPerPage: function() //{{{3
    {
        return this.max_events_in_block;
    },
    //3}}}
    setEventsPerPage: function( max_events_num ) //{{{3
    {
        this.max_events_in_block = max_events_num;
    },//3}}}
    remove_elements: function( elements_list ) // {{{3
    {
        // Remove element from page and clear recored ad ObjectLinker
        for ( var i = 0; i < elements_list.length; i ++  )
        {

            var elem = elements_list[i];
            this._eventObjectsLinker.deleteUiId( elem.id );
            $(elem).unbind();
            $(elem).find("*").unbind();
            $(elem).remove();
        }
    },//3}}}...remove_elements
    __processPauseEvents: function( newEvents ) //{{{3
    {
        if ( newEvents instanceof Array )
            this._numPauseEvents += newEvents.length;
        this._events = this._events.concat( newEvents );
        this._events.splice( this.max_events_in_block - 1,
                                        this._events.length );
    },
    //3}}}
    __linkify_link: function ( str ) //{{{3
    {
        //Makes links linkable
        var tmp_re = /[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/~.=]+/g;
        return str.replace( tmp_re,
            function( m )
            {
                var lnk = m.link(m);
                var re = /<a /g;
                return lnk.replace( re, '<a target="_blank" ' );
            });
    },
    //3}}}..__linkify_link
    __linkify_user: function( str ) //{{{3
    {
        return str.replace( /@\w+/g,
            function( m )
            {
                var net_user = m.substring( 1 );
                return $.format('<a href="http://twitter.com/{net_user}" target="_blank"> @{net_user} </a>',
                                    {net_user:net_user});
            });
    },
    //3}}}
    __linkify_tag: function( str ) //{{{3
    {
        str = ' ' + str;
        return str.replace( /[^&](#\w+)/g,
            function( m )
            {
                m   = m.split(' ').join( '' );
                var tag = m.substring(1);
                return ' ' + m.link(
                    $.format(window.location.pathname + '?q=tag:{tag}',
                                                            {tag:tag}) );
            } );
    }//3}}}...__linkify_tag
};
//2}}}...EventQueue.prototype
//1}}}...EventQueue class and prototype

function EventCommentsArea( actionJSelector ) //{{{1
{
    this.__init__( actionJSelector )
}

EventCommentsArea.prototype = {
    __init__: function( actionJSelector ) //{{{2
    {

        this.idsReader           = new IdentificatorsLinker();
        this.actionJSelector     = actionJSelector;
        this.actionsBlock        = $(actionJSelector).closest('div');
        this.isFetchSuccess      = false;
        this.hasConversationLink = false;
        this.spinnerInstance     = typeof SimpleSpinner != "undefined"?
                                    SimpleSpinner.getInstance(): undefined;

        this.rootTagId = $(this.actionJSelector).closest( 'li' ).attr( 'id' );

        this.eventId = this.idsReader.getHbaseId( this.rootTagId );
        if ( !this.eventId )
            this.eventId = this.rootTagId;
       
        this.commentsMainArea = this.__generateCommentsHtmlBlock();
        this.commentEQueue    = new EventQueue( this.commentsMainArea );
        this.commentEQueue.setIsComment(true);

        this.__requestComments();

        var _this = this;
        $( this.actionJSelector ).unbind();
        $( this.actionJSelector ).click( function(){
            return  _this.__toggleComments.apply( _this, arguments )
        });

        this.__slideSpeed = 700;
    },
    //2}}}...__init__
        //    ----------------------------
    __boundrayMethod: function( d_obj, method ) //{{{2
    {
        if ( !d_obj || !method )
            return false;
        return function()
        {
            return method.apply( d_obj, arguments );
        }
    },//2}}}
    __requestComments: function() //{{{2
    {
        if ( ! this.eventId )
            return;

        if ( this.spinnerInstance )
            this.spinnerInstance.createSpinner( "#" + this.rootTagId );

        var data = {'rootEventId': this.eventId};
        var json_msg = JSON.stringify( data );

        var _this = this;
        $.ajax({
            type: "POST",
            url: "/ajax/get_comments_by_eventid/",
            contentType: "appication/json; charset=utf-8",
            dataType: "json",
            data: {'requestParams': json_msg},
            success: function(){ 
                return _this.__ajaxcallback__requestComments.apply( _this, arguments )
            }
        });
    },
    //2}}}...__requestComments
    __generateCommentsHtmlBlock: function() //{{{2
    {
        var commentsHtmlBlock = '<div class="comment_details comment_slidedown"><ul></ul></div>';
        $( this.actionsBlock ).after( commentsHtmlBlock );
        //Return block identificator.
        return '#' + this.rootTagId + ' div.comment_slidedown>ul';
    },
    //2}}}...__generateCommentsHtmlBlock
    __ajaxcallback__requestComments: function( reply ) //{{{3
    {
        var result = reply.result;
        
        if ( this.spinnerInstance )
            this.spinnerInstance.removeSpinner( "#" + this.rootTagId );

        if ( !result || !result.events_list || !result.events_list.length )
            return;

        if ( ! reply.success )
        {
            this.isFetchSuccess = false;
            return;
        }
        
        this.isFetchSuccess = true;
        this.commentEQueue.addEventsUnchecked( result.events_list );
        this.commentEQueue.renderAllEvents(false, false);
        $(this.commentsMainArea).slideDown( this.__slideSpeed );
    },
    //2}}}...__ajaxcallback__requestComments
    __toggleComments: function( evnt ) //{{{2
    {
        evnt.preventDefault();
        if ( ! this.isFetchSuccess )
        {
            this.__requestComments();
            return;
        }
        this.commentEQueue.renderAllEvents(false);
        $('#' + this.rootTagId + ' div.comment_slidedown' ).remove();

        $( this.actionJSelector ).unbind();
        $( this.actionJSelector ).find( '*' ).unbind();
        this.commentEQueue.beforeDelete();
        delete this.commentEQueue;

        $( this.actionJSelector ).click( function()
        {
            $('#' + this.rootTagId + ' div.comment_slidedown').remove();
        	
            evnt.preventDefault();
            new EventCommentsArea( this );
        });        

        
    }
    //2}}}...__toggleComments
}
//1}}}...function EventCommentsArea

