/*jslint devel: true, browser: true, white: false, onevar: false, undef: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, nomen: false, bitwise: false */
/*global window: false, $: false, jQuery: false, $f: false */

function playposition() {
    var position = 0;
    // Check that the player is created (no splash img elements).
    if (jQuery('#mediaplayer img').length === 0) {
        try {
            position = $f('mediaplayer').getStatus().time;
        } catch (e) {}
    }
    if (position == undefined) {
        position = 0;
    }
    return position;
}

function HallInfo(options) {

    this.options = $.extend(true, {}, options);

    /* Current state polling frequency in millisecondsnds */
    this.current_state_poll_frequency = 1000 * 10;
    /* Members list polling frequency in milliseconds */
    this.attendants_and_history_poll_frequency = 1000 * 30;
    /* Active */
    this.active = true;
    /* Throttle */
    this.throttle = 0;
    /* Poll busy flag */
    this.poll_busy = false;
    /* Poll congestion rate */
    this.poll_waiting = 0;
    /* Poll congestion limit */
    this.poll_congestion_limit = 6;
    /* List of objects for different time periods and attendants in them. */
    this.attendant_history = null;

    this.statusdata = false;
    this.history_updated = false;
    this.attendants_updated = false;
    this.old_version = false;

    /* Tab ids */
    this.STATUSTAB = 0;
    this.DATATAB = 1;
    this.HISTORYTAB = 2;
    this.ATTENDANTSTAB = 3;

    /* timers */
    this.poll_timeout = null;
    this.lists_timeout = null;
    this.chapters_timeout = null;

    /* translations */
    this.i18n_data = {
        'fi': {
            'empty': 'Tyhjä',
            'away': 'Poissa',
            'label_response': 'repliikki',
            'says': 'Puheenvuorot',
            'voting': 'Äänestys',
            'moveto': 'Siirry kohtaan',
            'add_text': 'muokkaa',
            'cancel_edit': 'Peruuta',
            'save_text': 'Tallenna',
            'could_not_add_decision': 'Virhe päätöksen lisäämisessä.',
            'decision_title': 'Päätös',
            'end_of_the_meeting': 'Kokous on päättynyt',
            'no_player_message': '<h1>Videopalvelimella on ruuhkaa</h1><p>Videopalvelimen maksimikapasiteetti on saavutettu. Yritä myöhemmin uudelleen.</p>',
            'TYHJA': 'Tyhjä',
            'JAA': 'Jaa',
            'EI': 'Ei',
            'POISSA': 'Poissa',
            'show': 'näytä lisää',
            'hide': 'piilota',
            'map': 'Äänestyskartta'
        },
        'sv': {
            'empty': 'Blanka',
            'away': 'Frånvarande',
            'label_response': 'replik',
            'says': 'Inlägg',
            'voting': 'Omröstning',
            'moveto': 'Gå till punkt',
            'add_text': 'ändra',
            'cancel_edit': 'Avbryt',
            'save_text': 'Spara',
            'could_not_add_decision': 'Ökad beslutet fel.',
            'decision_title': 'Beslut',
            'end_of_the_meeting': 'Mötet är slut',
            'no_player_message': '<h1>Video servrar är upptagna</h1><p>Video Server maximal kapacitet är uppnådd. Försök igen senare.</p>',
            'TYHJA': 'Blanka',
            'JAA': 'Ja',
            'EI': 'Nej',
            'POISSA': 'Frånvarande',
            'show': 'visa mer',
            'hide': 'hide',
            'map': 'Karta'
        }
    };

}

/**
 * Helper function to generate voteresults
 */
HallInfo.prototype.generateVoteResults = function (item) {
    var info = this,
        $votes = jQuery('<ul id="aanestys"></ul>');
    jQuery.each(item, function (ai, aitem) {
        if (aitem.tulos) {
            var $vote = jQuery('<ul style="clear:both"></ul>'),
                $li=jQuery('<li></li>');
            if ((aitem.aanet != undefined) && (aitem.aanet.length > 0)) {
                var thumbnail = '<img style="float: right"' + 'alt="' + info.i18n('map') + '" ' + 'src="' + info.options.context_url + '/@@voting-map-thumbnail?end=' + aitem.end + '" />'
                $vote.append(jQuery('<li><a target="_blank" href="' + info.options.context_url + '/voting_map?end=' + aitem.end + '">' + thumbnail + '</a></li>'));

                $vote.append(jQuery('<li style="font-weight: bold"></li>').text(info.get_with_fallback(aitem, 'jaa-ots', 'jaa-teksti')+' (' + info.i18n('JAA') +'): '+aitem.tulos.jaa));
                $vote.append(jQuery('<li style="font-weight: bold"></li>').text(info.get_with_fallback(aitem, 'ei-ots', 'ei-teksti')+' (' + info.i18n('EI') +'): '+aitem.tulos.ei));
                $vote.append(jQuery('<li></li>').text(info.i18n('empty') + ': ' + aitem.tulos.tyhjia));
                $vote.append(jQuery('<li></li>').text(info.i18n('away') + ': ' + aitem.tulos.poissa));

                var $vts = jQuery('<li></li>');
                var $aanet=jQuery('<table class="aanet visualClear"><tr><th>' + info.i18n('JAA') + '</th><th>' + info.i18n('EI') + '</th></tr><tr><td class="JAA-aanet"></td><td class="EI-aanet"></td></tr><tr><th>' + info.i18n('TYHJA') + '</th><th>' + info.i18n('POISSA') + '</th></tr><tr><td class="TYHJA-aanet"></td><td class="POISSA-aanet"></td></tr></table>').hide();
                var avotes={'TYHJA': $aanet.find('.TYHJA-aanet'),
                            'JAA': $aanet.find('.JAA-aanet'),
                            'EI': $aanet.find('.EI-aanet'),
                            'POISSA': $aanet.find('.POISSA-aanet')}

                jQuery.each(aitem.aanet, function (vi, vote) {
                    avotes[vote.aani].append(jQuery('<p></p>').text(vote.hlo));
                });

                var $b_show=jQuery('<a class="show-voters-link"></a>').text(info.i18n('show'));
                var $b_hide=jQuery('<a class="hide-voters-link"></a>').text(info.i18n('hide'));
                $vts.append($b_show);
                $vts.append($b_hide.hide());
                $vts.append($aanet);
                $b_show.bind('click', function () {
                    var $parent=$(this).parent();
                    $parent.find(".aanet").show();
                    $(this).hide();
                    $parent.find(".hide-voters-link").show();
                });
                $b_hide.bind('click', function () {
                    var $parent=$(this).parent();
                    $(this).parent().find(".aanet").hide();
                    $(this).hide();
                    $parent.find(".show-voters-link").show();
                });
                $vote.append($vts);
            } else {
                $vote.append(jQuery('<li style="font-weight: bold"></li>').text(info.get_with_fallback(aitem, 'jaa-ots', 'jaa-teksti')+' (' + info.i18n('JAA') +'): '+aitem.tulos.jaa));
                $vote.append(jQuery('<li style="font-weight: bold"></li>').text(info.get_with_fallback(aitem, 'ei-ots', 'ei-teksti')+' (' + info.i18n('EI') +'): '+aitem.tulos.ei));
                $vote.append(jQuery('<li></li>').text(info.i18n('empty') + ': ' + aitem.tulos.tyhjia));
                $vote.append(jQuery('<li></li>').text(info.i18n('away') + ': ' + aitem.tulos.poissa));
            }
            $li.append($vote);
            $votes.append($li);
       }
    });
    return $votes;
};

/**
 * Refresh function to update status window
 */
HallInfo.prototype.refreshStatusData = function () {
    var info = this;

    /* Try to maintain only a single active poll at a time */
    this.poll_busy = false;
    if (this.poll_busy) {
        this.poll_waiting += 1;
        if (this.poll_waiting < this.poll_congestion_limit) {
            /* Let some poll requests be ignored to avoid congestion and therefore
            duplicate entries. */
            return;
        } else {
            /* Avoid dead-lock by letting the poll proceed if the congestion limit
            is exceeded. */
            this.poll_waiting = 0;
        }
    }

    this.poll_busy = true;

    if (info.options.is_livesession) {
        jQuery.getJSON(info.options.context_url + '/@@hallinfo-latest',
            function (data, status) {
                info.updateStatusData(data, true);
            }
        );
    } else {
        if (!info.statusdata) {
            jQuery.getJSON(info.options.context_url + '/@@hallinfo-annotations',
                function (data, status) {
                    info.statusdata = data;
                    info.updateStatusData(info.findClosestEvent(info.statusdata,
                        Math.round(playposition()+info.options.video_offset)), true);
                }
            );
        } else {
            info.updateStatusData(info.findClosestEvent(info.statusdata,
                Math.round(playposition()+info.options.video_offset)), true);
        }
    }
};


HallInfo.prototype.i18n = function (key) {
    return this.i18n_data[context_language][key];
};

HallInfo.prototype.get_with_fallback = function (o, key, key2) {
    var value = o[key];
    if (value == undefined) {
        return o[key2];
    }
    return value;
};


/*
 * Update data in status window
 */
HallInfo.prototype.updateStatusData = function (data, status) {

    if (!data) {
        return;
    }

    var info = this;
    /* Basic titles */
    var titles = ['asianumero','kohtaindeksi','asiateksti','kohtateksti'];
    jQuery.each(titles, function(i, item) {
        var tmp;
        if (data[item]) { tmp = data[item]; }
        else { tmp = "-"; }
        jQuery("#"+item).text(tmp);
        jQuery("#"+item).show();
        jQuery("#"+item).parent().show();
    });

    if (!data['kohtaindeksi'] || data['kohtaindeksi']=="0") {
        jQuery("#kohtaindeksi").parent().hide();
    }

    /* End of the meeting */
    var $state = jQuery(".current-status #tila");
    if (data.tila == 'kokous paattynyt') {
        $state.text(info.i18n('end_of_the_meeting'));
        $state.parent().show()
        jQuery.each(titles, function(i, item) {
            jQuery("#"+item).parent().hide();
        });
    } else {
        $state.parent().hide()
    }

    /* Message */
    var $message = jQuery("#tiedote");
    if (data.tiedote) {
        $message.text(data.tiedote);
    } else {
        $message.text('');
    }
    $message = jQuery("#tiedote_sv");
    if (data.tiedote_sv) {
        $message.text(data.tiedote_sv);
    } else {
        $message.text('');
    }
    if (data.tiedote || data.tiedote_sv) {
        $message.parent().show();
    } else {
        $message.parent().hide();
    };

    /* Speaker */
    var $speaker = jQuery("#puheenvuoro");
    if (data.puheenvuoro && data.puheenvuoro.henkilo) {
        $speaker.parent().show();
        $speaker.text(data.puheenvuoro.henkilo);
    } else {
        $speaker.parent().hide();
        $speaker.text('');
    }

    /* Reservations */
    var $puheenvuorovaraukset = jQuery('#puheenvuorovaraukset');
    $puheenvuorovaraukset.empty();

    var varaukset = data.puheenvuorovaraukset;
    var repliikit = data.repliikkivaraukset;
    if ((varaukset && varaukset.length>0) || (repliikit && repliikit.length>0)) {
        $puheenvuorovaraukset.parent().show();
    } else {
        $puheenvuorovaraukset.parent().hide();
    }

    jQuery.each(repliikit, function (i, item) {
        var liv = jQuery('<li></li>')
            .addClass('varaus')
            .text(item.henkilo);
        $puheenvuorovaraukset.append(liv);
    });
    jQuery.each(varaukset, function (i, item) {
        var liv = jQuery('<li></li>')
            .addClass('varaus')
            .text(item.henkilo);
        $puheenvuorovaraukset.append(liv);
    });

};

/**
 * Fetch the attendant history data and call the refreshAttendants function.
 */
HallInfo.prototype.fetchPresenceHistory = function () {

    var info = this;

    jQuery.getJSON(info.options.context_url + '/@@hallinfo-presence-history',
        function (data, status) {
            if (data && data !== 'null' && data.length > 0) {

                // Save fetched data and mark attendant updated.
                info.attendant_history = data;
                info.attendants_updated = true;
                // Refresh the attendant list.
                info.refreshAttendants();

            } else {

                // Fallback to old
                // Fetch the current attendants and update the list.
                jQuery.getJSON(info.options.context_url + '/@@hallinfo-attendants',
                               function (data, status) {
                                   if (data && data !== 'null' && data.paikat.length > 0) {
                                       info.old_version = true;
                                       info.attendant_history = data;
                                       info.attendants_updated = true;
                                       info.refreshAttendants();
                                   }
                               });
            }
    });

};

/**
 * Wrapper function for attendant list refreshing.
 *
 * Fetches the attendant list for live sessions and
 * calls the refreshAttendantList function to update
 * the list.
 *
 * For non-live sessions the attendant list fetching
 * function is called once and after updating the list
 * the refreshAttendantList function is just called
 * with the current data.
 */
HallInfo.prototype.refreshAttendants = function () {

    var info = this,
        playposition_offset = Math.round(playposition() + info.options.video_offset);

    if (info.options.is_livesession) {

        // Fetch the current attendants and update the list.
        jQuery.getJSON(info.options.context_url + '/@@hallinfo-attendants',
            function (data, status) {
                if (data && data !== 'null') {
                    info.refreshAttendantList(data);
                }
            });

    } else {

        // Fetch attendant JSON if the data has not been yet updated.
        if (!this.attendants_updated) {
            this.fetchPresenceHistory();
            return;
        }

        // Refresh the list with the current data.
        // Fallback to old
        if (!this.old_version) {
            var closest = this.findClosestEvent(this.attendant_history, playposition_offset);
            this.refreshAttendantList(closest);
        } else {
            // Fallback
            this.refreshAttendantList(this.attendant_history);
        }
    }
};

/**
 * Refreshes the attendant list by the given JSON object.
 */
HallInfo.prototype.refreshAttendantList = function (attendants) {

    var attendant_list = [],
        i, num_attendants,
        place, place_num, place_person, place_history,
        j, history_person,
        added_history_attendants = [],
        place_added = false;

    num_attendants = attendants.paikat ? attendants.paikat.length : 0;

    for (i = 0; i < num_attendants; i += 1) {

        place_added = false;

        place = attendants.paikat[i];
        place_num = place.paikka;
        place_person = place.henkilo;
        place_history = place.history;

        // Add person to the list if the num and the name are not empty.
        if (place_num && place_person) {
            attendant_list.push('<li class="henkilo">' + place_num +
                ' ' + place_person + '</li>');
            place_added = true;
        }

        // If there are persons in the history list, add them
        // below the current person.
        if (place_history && place_history.length > 0) {

            if (!place_added && place_num) {
                attendant_list.push('<li class="henkilo">' + place_num + ' -</li>');
            }

            for (j = 0; j < place_history.length; j += 1) {

                history_person = place_history[j].henkilo;

                // Add the person from history if it is not the same as the
                // current person on the place.
                if (history_person && history_person !== place_person &&
                    jQuery.inArray(history_person, added_history_attendants) === -1) {

                    attendant_list.push('<li class="henkilo henkilo-history">' +
                        history_person + '</li>');
                    added_history_attendants.push(history_person);
                }
            }
            added_history_attendants = [];
        }
    }

    if (attendant_list) {
        jQuery('#attendants').html(attendant_list.join(''));
    }

};

/**
 * Adds a link that opens an edit field for each case.
 */
HallInfo.prototype.addEditFields = function () {

    var info = this,
        addHtml = ' <a class="decision-link" href="#">' + info.i18n('add_text') + '</a>',

        editHtml = ['<textarea rows="5" cols="20"></textarea><br />',
                    '<input class="edit-decision-submit" type="button" value="',
                        info.i18n('save_text'), '">',
                    '<input class="edit-decision-cancel" type="button" value="',
                        info.i18n('cancel_edit'), '" />'
                   ].join('');

    // Add the edit links for each case.
    $('span.decision').append(addHtml);

    // Use event delegation to assing only one click handler
    // for the parent element and checking the target.
    $('#session-history').click(function (e) {

        var target = $(e.target),
            container = target.parent(),
            decision, decisionText = '',
            decisionLink, editArea, editAreaDom;

        if (target.is('a') && container.is('span.decision')) {

            // Add a global flag so that the content is not refreshed
            // while the edit form is in use.
            info.options.edit_field_open = true;

            decision = container.children('span.decision-text');
            decisionLink = container.children('a.decision-link');

            // Save added decision if one is found.
            if (decision && decision.html()) {
                decisionText = decision.data('decision_text');
            }

            decision.hide();
            decisionLink.hide();

            // Change the html and focus on the textarea.
            editArea = container.children('span.decision-edit').html(editHtml).fadeIn();
            editAreaDom = editArea.find('textarea').get(0);
            editAreaDom.value = decisionText;
            editAreaDom.focus();

            // Remove the edit field and show the link
            // if the cancel button is clicked.
            container.find('input.edit-decision-cancel').click(function (e) {
                editArea.fadeOut('normal', function () {
                    $(this).empty();
                    decision.show();
                    decisionLink.show();
                    info.options.edit_field_open = false;
                });
            });

            container.find('input.edit-decision-submit').click(function (e) {

                var editText = editArea.find('textarea').val();

                $.post(info.options.context_url + '/@@hallinfo-add-decision', {
                    paatos: editText,
                    snro: container.siblings('span.snro').text() || 'unknown'
                }, function (data, textStatus) {

                    if (data && typeof data.paatos === 'string' &&
                        typeof data.paatos_raw === 'string') {

                        // Remove the edit form and put the fetched text
                        // in the decision text element.
                        editArea.fadeOut('normal', function () {

                            var text = data.paatos_raw.replace(/\n/g, '\r\n'),
                            decisionTitle = decision.siblings('span.decision-title');

                            $(this).empty();
                            decision.html(info.htmlize(info.escape(data.paatos_raw))).show();
                            decision.data('decision_text', text);

                            // Show decision title only if the decision is non-empty.
                            if (text) {
                                decisionTitle.css('display', 'block');
                            } else {
                                decisionTitle.css('display', 'none');
                            }

                            decisionLink.show();
                            info.options.edit_field_open = false;
                        });

                    } else {
                        alert(info.i18n('could_not_add_decision'));
                    }
                }, 'json');

            });

            e.preventDefault();
        }
    });
};

/**
 * Refreshes meeting history from the backend.
 */
HallInfo.prototype.refreshHistory = function () {
    var info = this,
        context_url=jQuery('#videoContentWrapper .linkInfo input').attr('value');
    if (!info.options.is_livesession && info.history_updated) {
        return;
    } else if (info.options.edit_field_open) {
        // Don't update the content if the edit field is open.
        return;
    }
    jQuery.getJSON(info.options.context_url + '/@@hallinfo-meeting',
        function (data, status) {
            var $history = jQuery('#session-history');
            $history.empty();

            if (!data) {
                return;
            }
            $.each(data.asiat, function (i, item) {
                if (item.asia.asianumero) {
                    if (item.asia.kohtanumero != 0) {
                        var span1 = jQuery('<span></span>')
                            .addClass('kohtanumero')
                            .text(item.asia.kohtaindeksi);
                        var span2 = jQuery('<span></span>')
                            .addClass('kohtateksti');
                        if (item.asia.kohtateksti_sv == undefined) {
                            span2 = span2.text(item.asia.kohtateksti);
                        } else {
                            span2 = span2.text(item.asia.kohtateksti + " " + item.asia.kohtateksti_sv);
                        }
                    } else {
                        var span1 = jQuery('<span></span>')
                            .addClass('asianumero')
                            .text(item.asia.asianumero);
                        var span2 = jQuery('<span></span>')
                            .addClass('asiateksti');
                        if (item.asia.asiateksti_sv == undefined) {
                            span2 = span2.text(item.asia.asiateksti);
                        } else {
                            span2 = span2.text(item.asia.asiateksti + " " + item.asia.asiateksti_sv);
                        }
                    }

                    if (!info.options.is_livesession && item.asia.second) {
                        span2 = span2.wrap('<a class="jump-to-title" href="' + context_url + '#' + info.play_pos(item.asia.second, true) + '" title="' +
                                           info.i18n('moveto') + '"></a>').parent();
                        span2.click(function (e) {
                            // Have to make an extra closure to
                            // get the right argument in a loop.
                            (function (second) {
                                info.seek(second, true);
                            }(item.asia.second));
                            e.preventDefault();
                        });
                    }

                    var li = jQuery('<li></li>')
                        .addClass('asiakohta')
                        .append(span1)
                        .append(span2)
                        .append('<span class="snro" style="display:none;">' + item.asia.snro + '</span><br />');

                    li.append('<span class="decision"><span class="decision-title">' + info.i18n('decision_title') +
                              ':</span><span class="decision-text"></span>' +
                              '<span class="decision-edit"></span></span>');

                    if (item.asia.paatos) {
                        li.find('span.decision-title').css('display', 'block');
                        li.find('span.decision-text').html(
                            info.htmlize(info.escape(item.asia.paatos))).data('decision_text',
                                                                 item.asia.paatos.replace(/\n/g, '\r\n'));
                    }

                    if (item.puheenvuorot.length>0) {
                        li.append($('<span class="header">' + info.i18n('says') + '</span>'));
                        var puheenvuorot = jQuery('<table id="puheenvuorot" class="puheenvuorot"></table>');
                        $.each(item.puheenvuorot, function (pi, pitem) {
                            var pli = jQuery('<tr></tr>').addClass('henkilo'),
                                speakerHtml = pitem.henkilo + '<span style="display:none;">' + pitem.second + '</span>';

                            if (!info.options.is_livesession) {
                                speakerHtml = '<a href="' + context_url + '#' + info.play_pos(pitem.second, true) + '" class="jump-to-link" title="' +
                                    info.i18n('moveto') + '">' + speakerHtml + '</a>';
                            }

                            pli.append(jQuery('<td></td>').html(speakerHtml));

                            // Display the duration if it is defined, otherwise an empty element.
                            if (pitem.duration) {
                                pli.append(jQuery('<td></td>').addClass('small').text(
                                    Math.round(pitem.duration/60)+':'+info.zpad(pitem.duration%60)+' min'));
                            } else {
                                pli.append('<td class="small"></td>');
                            }
                            puheenvuorot.append(pli);
                        });


                        li.append(puheenvuorot);
                    }
                    if (item.aanestykset.length>0) {
                        li.append('<span class="header">' + info.i18n('voting') + '</span>');
                        li.append(info.generateVoteResults(item.aanestykset));
                    }

                    $history.append(li);
                }
            });

            $('table.puheenvuorot').click(function (e) {

                var target = $(e.target),
                    seekSeconds;

                if (target.is('a.jump-to-link')) {
                    try {
                        seekSeconds = parseInt(target.children('span').html(), 10);
                    } catch(err) {
                        return false;
                    }

                    info.seek(seekSeconds, true);
                    e.preventDefault();

                }
            });

            info.history_updated = true;

            // Add a link that opens an inline edit field for
            // each case for editor users.
            if (info.options.is_editor) {
                info.addEditFields();
            }
        });
};

// Binary search to find closest action node from annotated list.
// Returned value is always smaller
HallInfo.prototype.findClosestEvent = function(o, v){
    var h = o.length, l = -1, m;
    while(h - l > 1) {
        m = (h + l) >> 1;
        if(o[m].second <= v) {
            l = m;
        } else {
            h = m;
        }
    }
    return o[(l>0)?l:0];
};

// Convert 0 -> 00, 1 -> 01 , etc
HallInfo.prototype.zpad = function (i) {
    return (i.toString().length === 1) ? '0' + i.toString() : i.toString();
};

HallInfo.prototype.play_pos = function (seconds, substractOffset) {
    return Math.max(0, seconds - (substractOffset ? this.options.video_offset : 0));
};


/**
 * Correct embed and link to the new play position.
 */
HallInfo.prototype.change_links = function (play_position) {
    var $link=jQuery('#videoContentWrapper .linkInfo input.selectOnClick');
    var $embed=jQuery('#videoContentWrapper .embedInfo textarea.selectOnClick');
    if ($link.length) {
        $link.attr('value', $link.attr('value').split("#")[0] + "#" + play_position);
    }
    if ($embed.length) {
        $embed.html($embed.html().replace(/\/embed\?(seekto=[0-9]+)?[&]?/, '/embed?seekto='+ play_position +'&'));
    }
}

/**
 * Seeks the player to the specified position.
 * Starts the player if it not yet playing.
 */
HallInfo.prototype.seek = function (seconds, substractOffset) {

    var info = this,
        player = $f('mediaplayer'),
        playPosition = info.play_pos(seconds, substractOffset);

    info.change_links(playPosition);

    // Check that the player is created (no splash img elements)
    // and that is already playing.
    if ($('#mediaplayer img').length === 0 && player.isPlaying()) {
        player.seek(playPosition);
    } else {

        // If the player is not yet playing, we must first
        // make it start playing for a while until calling
        // the seek method.
        player.play();

        setTimeout(function () {
            if (info.active) {
                player.seek(playPosition);
            }
        }, 1000);
    }

};

/**
 * Replace linebreaks with br tags and put paragraphs inside p tags.
 */
HallInfo.prototype.htmlize = function (s) {
    // We have to leave the line breaks (\n) in so that
    // the content can be put to the textarea again.

    return '<p>' +
        s.replace(/\n\n/g, '</p><p>').
        replace(/\n/g, '<br />') +
        '</p>';
};

HallInfo.prototype.escape = function (s) {
    return s.
        replace(/&/g, '&amp;').
        replace(/</g, '&lt;').
        replace(/>/g, '&gt;').
        replace(/"/g, '&quot;').
        replace(/'/g, '&#39;');
};


/**
 * Polls the backend server indefinitely for attendants & history.
 */
HallInfo.prototype.lists = function () {
    var info = this;
    if (info.active && info.attendants_and_history_poll_frequency > 0) {
        var _selected_tab = jQuery('#session-data').tabs().tabs('option', 'selected');
        if (_selected_tab === info.HISTORYTAB) {
            info.refreshHistory();
        }
        if (_selected_tab === info.ATTENDANTSTAB) {
            info.refreshAttendants();
        }
        this.lists_timeout = setTimeout(function () {
            if (info.active) {
                (function () { this.lists();}).apply(info);
            }
        }, info.attendants_and_history_poll_frequency);
    }
};
/**
 * Polls the backend server indefinitely for new status.
 */
HallInfo.prototype.poll = function () {
    var info = this;
    if (info.active && info.current_state_poll_frequency > 0) {
        var _selected_tab = jQuery('#session-data').tabs().tabs('option', 'selected');
        if (_selected_tab === info.STATUSTAB) {
            info.refreshStatusData();
        }
        this.poll_timeout = setTimeout(function () {
            if (info.active) {
                (function () { this.poll();}).apply(info);
            }
        }, info.current_state_poll_frequency);
    }
};

HallInfo.prototype.activate_player = function () {
    jQuery('#portal-column-content a.hkmediacontent').primacontrolflowplayer({
        'portal_url': helsinkikanava_portal_url,
        'flowplayer_key': flowplayer_key
    });
};

HallInfo.prototype.close = function () {
    var info = this;
    info.active = false;
    if (info.poll_timeout !== null) {
        clearTimeout(info.poll_timeout);
        info.poll_timeout = null;
    }
    if (info.lists_timeout !== null) {
        clearTimeout(info.lists_timeout);
        info.lists_timeout = null;
    }
    if (info.chapters_timeout !== null) {
        clearTimeout(info.chapters_timeout);
        info.chapters_timeout = null;
    }
};

HallInfo.prototype.init = function () {
    var info = this;

    // Tabs
    jQuery('#session-data').tabs();
    // Show tab content after onload to avoid unstyled content.
    jQuery('#hallSessionVideoRelatedContent').css('visibility', 'visible');

    // Chapter selector box functionality
    jQuery('#chapters').change(function() {
        info.seek(jQuery(this).val(), false);
        if (info.chapters_timeout !== null) {
            clearTimeout(info.chapters_timeout);
            info.chapters_timeout = null;
        }
        info.chapters_timeout = setTimeout(function () {
            if (info.active) {
                jQuery('#chapters option').removeAttr('selected');
                info.chapters_timeout = null;
            }
        }, 5000);
    });

    jQuery("#puheenvuoro").parent().hide();
    jQuery('#puheenvuorovaraukset').parent().hide();


    if (info.options.is_livesession) {
        /* For live session check the backend */
        jQuery.getJSON(info.options.context_url + '/@@show-player',
            function (data, status) {
                if (data.show_player) {
                    info.activate_player();
                } else {
                    jQuery('#portal-column-content a.hkmediacontent')
                        .replaceWith('<div id="no-player">' +
                                       '<div class="ui-overlay"><div class="ui-widget-overlay"></div><div class="ui-widget-shadow ui-corner-all"></div></div>' +
                                       '<div class="ui-widget ui-widget-content ui-corner-all">' + info.i18n('no_player_message') + '</div>' +
                                     '</div>');
                }
        });
    } else {
        info.activate_player();
    }

    if (jQuery('#session-data').length) {
        // Polling data
        info.poll();
        info.lists();

        jQuery('#session-data > ul a').bind('click', function () {
            var _selected_tab = jQuery('#session-data').tabs().tabs('option', 'selected');
            if (_selected_tab === info.STATUSTAB) {
                info.refreshStatusData();
            }
            if (_selected_tab === info.HISTORYTAB) {
                info.refreshHistory();
            }
            if (_selected_tab === info.ATTENDANTSTAB) {
                info.refreshAttendants();
            }
        });
    }

    // Seek player to position 'seekto' if such param defined
    // Method is used links on external sites.
    if (window.location.search.split("?").length === 2) {
        var urlparam = window.location.search.split("?")[1].split("=");
        if (urlparam[0] === "seekto") {
            setTimeout(function () {
                if (info.active) {
                    info.seek(urlparam[1], false);
                }
            }, 1000);
        }
    }
};


jQuery(function () {
    var stext=jQuery.url.param("SearchableText");
    if (stext) {
        jQuery(".extraSearchResultsButton").click(
            function (e) {
                var $tgt=jQuery(e.target),
                    vurl=$tgt.attr("href"),
                    sid=$tgt.attr("id"),
                    divid="div" + sid,
                    hid="h" + sid;
                jQuery("#" + divid).show();
                jQuery("#" + divid).load(vurl+'/@@search-meeting?SearchableText=' + stext);
                jQuery("#" + hid).show();
                jQuery("#" + sid).hide();
                e.preventDefault();
            }
        );
        jQuery(".extraSearchResultsHideButton").click(
            function (e) {
                var $tgt=jQuery(e.target),
                    hid=$tgt.attr("id"),
                    sid = hid.substring(1, hid.length),
                    divid="div" + sid;
                jQuery("#" + divid).hide();
                jQuery("#" + hid).hide();
                jQuery("#" + sid).show();
                e.preventDefault();
            }
        );
        jQuery(".extraSearchResultsButton").show();
    }
});

