/// <reference path="../../ScriptReference/jquery-1.7.1-vsdoc.js"/>
/// <reference path="../../Scripts/Mediasite.Core.js"/>
/// <reference path="../../Scripts/Mediasite.Player.Core.js"/>
/// <reference path="../../Scripts/Mediasite.Player.Localization.js"/>
/*global Mediasite, Silverlight*/

Mediasite.namespace("Player");

Mediasite.Player.ViewLoader = function (dataProvider, playerContext) {

    var controller = new Mediasite.Player.Controller(dataProvider);
    var view = new Mediasite.Player.ScreenReaderView();
    var markupUrl = 'Javascript/Players/ScreenReader/ScreenReader.html';

    dataProvider.LoadMarkup(markupUrl);
    var mediaModelOptions = $.extend({}, Mediasite.MediaPlayer.ViewOptions,
    {
        mediaPlayerType: playerContext.GlobalOptions.PlayerContentPlugin.MediaPlayerType,
        pluginMimeType: playerContext.GlobalOptions.PlayerContentPlugin.MimeType,
        backgroundElement: $('#mediaElementArea'),
        playButtonText: Mediasite.Player.Localization.Buttons.Play,
        isMobile: Mediasite.BrowserDetect.Mobile(),
        height: Mediasite.PlayerLayoutOptions.VideoHeight,
        width: Mediasite.PlayerLayoutOptions.VideoWidth,
        liveSmoothStreamingOffset: Mediasite.GlobalOptions.LiveSmoothStreamingOffset,
        startPosition: playerContext.PlaybackOptions.StartPosition,
        autoStart: playerContext.PlaybackOptions.AutoStart,
        pauseAt: playerContext.PlaybackOptions.PauseAt
    });

    controller.LoadPlayer(view, mediaModelOptions);
};

Mediasite.Player.ScreenReaderView = function () {
    var $ = jQuery;

    var presentation;
    var slideStream;
    var streamViewHandlers = [];
    var currentPosition;
    var mediaDuration;
    var volume;
    var liveEnded = false;

    var linkRegEx = /\bhttps?:\/\/[-A-Z0-9+&@\/%=~_|!:,.;]+\/Play\/[-A-Z0-9+&@#\/%?=~_|!:,.;]+[-A-Z0-9+&@#\/%=~_|]/ig;
    var emailRegEx = /^[A-Z0-9.'_%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$/i;

    var _events = new Mediasite.Player.EventBundle();
    var _eventNames = Mediasite.Player.ViewEvent;
    var self = this;

    function fireClickCommand(command) {
        _events.fire(_eventNames.ClickCommand, command);
    }

    this.SlideStreamType = Mediasite.ContentStreamType.Slide;
    this.ContentCapability = Mediasite.Player.ContentCapability.VideoAndSlides;

    this.AddEventHandler = function (eventName, handler) {
        _events.addHandler(eventName, handler);
    };

    function validateEmailAddress(address) {
        return emailRegEx.test(address);
    }

    function validateEmailMessage(from, recipients) {
        var errors = 0;

        if (!validateEmailAddress(from)) {
            errors++;
        }

        var valid = 0;
        $.each(recipients, function (i) {
            if (!validateEmailAddress(recipients[i])) {
                errors++;
            }
            else {
                valid++;
            }
        });

        if (errors > 0 || valid < 1) {
            $('#sendEmailSubmitResult').text(Mediasite.Player.Localization.Email.InviteInvalid);
            return false;
        }

        return true;
    }

    function validateQuestion() {

        var errors = "";

        if ($('#questionName').val().length < 1) {
            errors += Mediasite.Player.Localization.AskQuestion.NameRequired + ". ";
        }
        if ($('#questionEmail').val().length > 0 && !validateEmailAddress($('#questionEmail').val())) {
            errors += Mediasite.Player.Localization.AskQuestion.QuestionRequired + ". ";
        }
        if ($('#questionSubject').val().length < 1) {
            errors += Mediasite.Player.Localization.AskQuestion.SubjectRequired + ". ";
        }
        if ($('#questionBody').val().length < 1) {
            errors += Mediasite.Player.Localization.AskQuestion.QuestionRequired + ". ";
        }

        if (errors.length > 0) {
            $('#questionSubmitResult').html(Mediasite.Player.Localization.AskQuestion.ValidationError + " " + errors);

            return false;
        }

        return true;
    }

    function getDisplayFromDuration(durationInMS, padZeros) {
        if (durationInMS < 0) {
            return "";
        }
        var whole = durationInMS;

        var hours = Math.floor(whole / 3600000);
        whole = whole - (hours * 3600000);

        var minutes = Math.floor(whole / 60000);
        whole = whole - (minutes * 60000);
        var seconds = Math.floor(whole / 1000);

        whole = whole - (seconds * 1000);

        var display = "";

        if (hours === 1) {
            display += (hours + " " + Mediasite.Player.Localization.Common.Hour + " ");
        }
        else if (hours > 0 || padZeros) {
            display += (hours + " " + Mediasite.Player.Localization.Common.Hours + " ");
        }

        if (minutes === 1) {
            display += (minutes + " " + Mediasite.Player.Localization.Common.Minute + " ");
        }
        else if (minutes > 0 || padZeros) {
            display += (minutes + " " + Mediasite.Player.Localization.Common.Minutes + " ");
        }

        if (seconds === 1) {
            display += (seconds + " " + Mediasite.Player.Localization.Common.Second);
        }
        else if (seconds > 0 || padZeros) {
            display += (seconds + " " + Mediasite.Player.Localization.Common.Seconds);
        }
        return display;
    }

    function getShortDisplayFromDuration(durationInMS, padHours) {
        if (durationInMS < 0) {
            return "";
        }
        var whole = durationInMS;

        var hours = Math.floor(whole / 3600000);
        whole = whole - (hours * 3600000);
        if (hours < 10) {
            hours = "0" + hours;
        }

        var minutes = Math.floor(whole / 60000);
        whole = whole - (minutes * 60000);
        var seconds = Math.floor(whole / 1000);

        whole = whole - (seconds * 1000);

        if (minutes < 10) {
            minutes = "0" + minutes;
        }
        if (seconds < 10) {
            seconds = "0" + seconds;
        }
        if (hours === "00" && !padHours) {
            return (minutes + ":" + seconds);
        }
        return (hours + ":" + minutes + ":" + seconds);
    }

    function getDurationFromShortDisplay(durationDisplay) {
        var i, segments = durationDisplay.split(":");

        for (i = 0; i < segments.length; i++) {
            segments[i] = parseInt(segments[i], 10);
            if (isNaN(segments[i])) {
                return 0;
            }
        }

        var timeInMS = 0;

        switch (segments.length) {
            case 3:
                timeInMS = segments[0] * 3600000 + segments[1] * 60000 + segments[2] * 1000;
                break;
            case 2:
                timeInMS = segments[0] * 60000 + segments[1] * 1000;
                break;
            case 1:
                timeInMS = segments[0] * 1000;
                break;
        }

        return timeInMS;
    }

    function sendEmail() {

        var recipients = [];
        $.each($('#sendEmailTo').val().split(";"), function (i, val) {
            if ($.trim(val).length > 0) {
                recipients.push($.trim(val));
            }
        });

        var from = $.trim($('#sendEmailFrom').val());

        if (validateEmailMessage(from, recipients)) {
            var invite = {
                ToAddresses: recipients,
                FromAddress: from,
                Subject: $('#sendEmailSubject').val(),
                MessageBody: $('#sendEmailBody').val(),
                Time: getDurationFromShortDisplay($('#sendEmailTime').val())
            };

            _events.fire(_eventNames.SendEmail, invite);
        }
    }


    function sendQuestion() {

        if (validateQuestion()) {
            var timeInPreso = getDurationFromShortDisplay($('#questionTime').val());

            var question = {
                Submitter: $('#questionName').val(),
                SubmitterEmail: $('#questionEmail').val(),
                Subject: $('#questionSubject').val(),
                QuestionText: $('#questionBody').val(),
                TimeInPresentation: timeInPreso
            };

            _events.fire(_eventNames.SendQuestion, question);
        }
    }

    function updateEmailText() {

        var startTimeMS = getDurationFromShortDisplay($('#sendEmailTime').val());
        var messageText = $('#sendEmailBody').val();

        var playLinkMatches = linkRegEx.exec(messageText);
        if (playLinkMatches === null) {
            return;
        }

        var playLink = playLinkMatches[0].replace(/([\?&])?playFrom=\d+&?/ig, '$1').replace(/[\?&]$/, '');
        if (startTimeMS > 0) {
            playLink += (playLink.indexOf('?') > 0 ? '&' : '?') + 'playFrom=' + startTimeMS;
        }

        $('#sendEmailBody').val(messageText.replace(linkRegEx, playLink));
    }


    function setMailToLink() {
        var link = "mailto:" + encodeURIComponent($('#sendEmailTo').val()) + "?subject=" + encodeURIComponent($('#sendEmailSubject').val()) + "&body=" + encodeURIComponent($('#sendEmailBody').val());
        if (link.length > 2000) {
            link = "mailto:" + encodeURIComponent($('#sendEmailTo').val()) + "?subject=" + encodeURIComponent($('#sendEmailSubject').val()) + "&body=" + encodeURIComponent(window.location.href);
        }
        $('#sendEmailUseClientLink').attr('href', link);
    }

    this.LoadLayout = function () {

        $('#standardPlayerPrompt').text(Mediasite.Player.Localization.ScreenReader.StandardPlayerPrompt);

        $('#presentationDescriptionLabel').text(Mediasite.Player.Localization.PresentationCard.Description);
        $('#presentationPresentersLabel').text(Mediasite.Player.Localization.PresentationCard.Presenters);
        $('#presentationAirTimeLabel').text(Mediasite.Player.Localization.PresentationCard.AirTime);
        $('#presentationAirDateLabel').text(Mediasite.Player.Localization.PresentationCard.AirDate);
        $('#presentationDurationLabel').text(Mediasite.Player.Localization.PresentationCard.Duration);

        $('#slideListHeader').text(Mediasite.Player.Localization.Common.SlideList);
        $('#chapterHeader').text(Mediasite.Player.Localization.Buttons.Chapters);
        $('#linkHeader').text(Mediasite.Player.Localization.Buttons.Links);
        $('#btnPlayPause').text(Mediasite.Player.Localization.Buttons.Play).attr("disabled", "disabled");
        $('#btnSkipBack').text(Mediasite.Player.Localization.Buttons.Skipback).attr("disabled", "disabled");
        $('#btnMute').text(Mediasite.Player.Localization.Buttons.Mute).attr("disabled", "disabled");
        $('#mediaControls').attr("aria-label", Mediasite.Player.Localization.ScreenReader.MediaControls);

        $('#btnPlayFaster').text(Mediasite.Player.Localization.Buttons.PlayFaster);
        $('#btnPlaySlower').text(Mediasite.Player.Localization.Buttons.PlaySlower);
        $('#currentPlaybackRate').text(Mediasite.Player.Localization.ScreenReader.PlaybackRate + ": 1x");
        $('#btnVolumeIncrease').text(Mediasite.Player.Localization.ScreenReader.VolumeIncrease);
        $('#btnVolumeDecrease').text(Mediasite.Player.Localization.ScreenReader.VolumeDecrease);

        $('#questionHeader').text(Mediasite.Player.Localization.Buttons.Ask);
        $('#questionLabelName').text(Mediasite.Player.Localization.AskQuestion.Name);
        $('#questionLabelEmail').text(Mediasite.Player.Localization.AskQuestion.Email);
        $('#questionLabelSubject').text(Mediasite.Player.Localization.AskQuestion.Subject);
        $('#questionLabelBody').text(Mediasite.Player.Localization.AskQuestion.Question);
        $('#questionLabelTime').text(Mediasite.Player.Localization.AskQuestion.Time);
        $('#questionUseCurrentTime').text(Mediasite.Player.Localization.ScreenReader.UseCurrentTime);
        $('#questionSubmit').text(Mediasite.Player.Localization.ScreenReader.SendQuestion);

        $('#sendEmailHeader').text(Mediasite.Player.Localization.Buttons.Email);
        $('#sendEmailUseClientLink').text(Mediasite.Player.Localization.ScreenReader.ShareUsingEmailClient);
        $('#sendEmailLabelTo').text(Mediasite.Player.Localization.Email.To);
        $('#sendEmailLabelFrom').text(Mediasite.Player.Localization.Email.From);
        $('#sendEmailLabelSubject').text(Mediasite.Player.Localization.Email.Subject);
        $('#sendEmailLabelBody').text(Mediasite.Player.Localization.Email.Message);
        $('#sendEmailLabelTime').text(Mediasite.Player.Localization.Email.Time);
        $('#sendEmailUseCurrentTime').text(Mediasite.Player.Localization.ScreenReader.UseCurrentTime);
        $('#sendEmailSubmit').text(Mediasite.Player.Localization.ScreenReader.SendEmail);

        _events.fire(_eventNames.LayoutLoaded);
    };

    this.GetStreamViewHandler = function (displayContent) {

        if (streamViewHandlers.length == 2) return undefined;

        var streamViewHandler = undefined;
        if (displayContent == Mediasite.ContentType.Video) {
            streamViewHandler = new Mediasite.Player.StreamViewHandler(
            {
                MediaContainer: $('#mediaElementArea'),
                UpdateCurrentSlide: function () { }
            });
            streamViewHandlers.push(streamViewHandler);
        } else {
            streamViewHandler = new Mediasite.Player.StreamViewHandler(
            {
                MediaContainer: undefined,
                UpdateCurrentSlide: self.UpdateCurrentSlide
            });
            streamViewHandlers.push(streamViewHandler);
        }

        return streamViewHandler;
    };

    function hasSlides() {
        if (!presentation || !slideStream) return false;

        if (isOnDemand()) {
            return slideStream.Slides.length > 0;
        } else {
            return slideStream.HasSlideContent && true;
        }
    }

    function isOnDemand() {
        return presentation.PlayStatus === Mediasite.Player.PresentationStatus.OnDemand;
    }

    this.SendEmailComplete = function (success, message) {
        $('#sendEmailSubmitResult').text(message);

        if (success) {
            $('#sendEmailTo').val("");
        }
    };

    this.SendQuestionComplete = function (success, message) {

        if (success) {
            $('#questionSubmitResult').text(Mediasite.Player.Localization.AskQuestion.SendSuccessDetail);
            $('#questionSubject').val("");
            $('#questionBody').val("");
        }
        else {
            var errorMessage = Mediasite.Player.Localization.AskQuestion.SendFailureDetail;
            if (message.length > 0) {
                errorMessage = errorMessage + ' ' + message;
            }
            $('#questionSubmitResult').text(errorMessage);
        }
    };

    this.ShowErrorMessage = function (message, details) {
        $('#errorMessage').text(message + " " + details);
    };

    this.UpdateCurrentSlide = function (slide) {
        if (slide.Number === 0) {
            $('#currentSlideTitle').text("");
            $('#currentSlideDescription').text("");
        }
        else {
            $('#currentSlideTitle').text(Mediasite.Player.Localization.Common.Slide + " " + slide.Number + " - " + slide.Text);
            $('#currentSlideDescription').text(slide.Description);
        }
    };

    this.UpdateEmailInvite = function (emailData) {
        $('#sendEmailSubject').val(emailData.Subject);
        $('#sendEmailBody').val(emailData.Message);
        $('#sendEmailTo').val("");

        if (!emailData.UseServerForSMTP) {
            $('#sendEmailServerForm').hide();
        }
    };

    this.UpdateMediaInfo = function (mediaInfo) {
        mediaDuration = mediaInfo.Duration;

        $('#btnVolumeIncrease').click(function () { _events.fire(_eventNames.VolumeChanged, Math.min(volume + 1, 100)); });
        $('#btnVolumeDecrease').click(function () { _events.fire(_eventNames.VolumeChanged, Math.max(volume - 1, 0)); });

        if (mediaInfo.CanChangeSpeed) {
            $('.playbackRateControls').show();
            $('#btnPlaySlower').click(function () { fireClickCommand(Mediasite.Player.ClickCommand.PlaySlower); });
            $('#btnPlayFaster').click(function () { fireClickCommand(Mediasite.Player.ClickCommand.PlayFaster); });
        }
    };

    this.UpdateMediaState = function (state) {
        var mediaStateText = (state === Mediasite.Player.MediaState.Undefined) ? '' : Mediasite.Player.MediaState.GetDisplayName(state);
        $("#mediaState").text(mediaStateText);

        switch (state) {
            case Mediasite.Player.MediaState.Playing:
                $('#btnPlayPause')
                    .text(Mediasite.Player.Localization.Buttons.Pause).removeAttr("disabled")
                    .unbind()
                    .click(function () { fireClickCommand(Mediasite.Player.ClickCommand.TogglePlayPause); });
                break;
            case Mediasite.Player.MediaState.Paused:
                $('#btnPlayPause')
                    .text(Mediasite.Player.Localization.Buttons.Play).removeAttr("disabled")
                    .unbind()
                    .click(function () { fireClickCommand(Mediasite.Player.ClickCommand.TogglePlayPause); });
                break;
            case Mediasite.Player.MediaState.Stopped:
                if (liveEnded) {
                    $('#btnPlayPause')
                    .attr("disabled", "true")
                    .unbind();
                }
                else {
                    $('#btnPlayPause')
                    .text(Mediasite.Player.Localization.Buttons.Play).removeAttr("disabled")
                    .unbind()
                    .click(function () { fireClickCommand(Mediasite.Player.ClickCommand.TogglePlayPause); });
                }
                break;
            case Mediasite.Player.MediaState.MediaEnded:
                $('#btnPlayPause')
                    .text(Mediasite.Player.Localization.Buttons.Play).removeAttr("disabled")
                    .unbind()
                    .click(function () { fireClickCommand(Mediasite.Player.ClickCommand.TogglePlayPause); });
                break;
            default:
                break;
        }
    };

    this.UpdateMediaVolume = function (vol) {
        volume = vol;
        if (volume > 0) {
            $("#btnMute")
                .text(Mediasite.Player.Localization.Buttons.Mute).removeAttr("disabled")
                .unbind()
                .click(function () { fireClickCommand(Mediasite.Player.ClickCommand.Mute); });
        }
        else {
            $("#btnMute")
                .text(Mediasite.Player.Localization.Buttons.UnMute).removeAttr("disabled")
                .unbind()
                .click(function () { fireClickCommand(Mediasite.Player.ClickCommand.Mute); });
        }

        $('#volumeLevel').text(Mediasite.Player.Localization.Common.Volume + ": " + volume);
    };

    this.UpdatePlaybackRate = function (rateInfo) {
        if (rateInfo.Current <= rateInfo.Min) {
            $("#btnPlaySlower").hide();
        }
        else {
            $("#btnPlaySlower").show();
        }

        if (rateInfo.Current >= rateInfo.Max) {
            $("#btnPlayFaster").hide();
        }
        else {
            $("#btnPlayFaster").show();
        }

        $('#currentPlaybackRate').text(Mediasite.Player.Localization.ScreenReader.PlaybackRate + ": " + rateInfo.Current + "x");

    };

    this.UpdatePosition = function (position) {
        currentPosition = position;

        if (mediaDuration > 0) {
            $('#mediaPosition').text(getDisplayFromDuration(position) + " " + Mediasite.Player.Localization.Common.Of + " " + getDisplayFromDuration(mediaDuration));
        }
        else {
            $('#mediaPosition').text(getDisplayFromDuration(position));
        }
    };

    this.UpdatePresentationData = function (modelPresentation) {
        presentation = modelPresentation;

        slideStream = presentation.GetStream(this.SlideStreamType);

        $(document).bind("keyup", function (event) {
            if ((event.keyCode === 32)      // Space
                && $(event.target).is('button,input,textarea')) { // Input elements

                // Do not toggle Play/Pause when focused on an input element

                return;
            }

            _events.fire(_eventNames.KeyCommand, event);
        });

        $('#presentationTitle').text(presentation.Title);
        $('#presentationDescription').html(presentation.Description.replace(/\r/g, "").replace(/\n/g, "<br>").replace(/\&/g, "&amp;"));
        $('#presentationAirDate').text(presentation.Date);
        $('#presentationAirTime').text(presentation.Time);
        $('#presentationDuration').text(getDisplayFromDuration(presentation.Duration, false));

        if (presentation.PlayStatus === Mediasite.Player.PresentationStatus.OnDemand) {
            $("#btnSkipBack").removeAttr("disabled")
                .click(function () { fireClickCommand(Mediasite.Player.ClickCommand.SkipBack); });
        }

        $.each(presentation.Presenters, function (i) {
            var item;
            if (presentation.Presenters[i].BioUrl.length > 0) {
                item = $('<li><a href="' + presentation.Presenters[i].BioUrl + '" target="_blank">' + presentation.Presenters[i].Name + '</a></li>');
            }
            else {
                item = $('<li>').text(presentation.Presenters[i].Name);
            }
            $('#presentationPresenters').append(item);
        });

        if (hasSlides()) {
            $.each(slideStream.Slides, function (i) {
                var item = $('<li role="listitem">');
                item.append($('<button role="button" aria-describedby="slideItem' + i + '">').text(Mediasite.Player.Localization.Common.Slide + ' ' + (i + 1)).click(function () { _events.fire(_eventNames.SlideChanged, i + 1); }));
                item.append($('<div id="slideItem' + i + '">').text(slideStream.Slides[i].Description));
                $('#slideList').append(item);
            });
        }


        $.each(presentation.Chapters, function (i) {

            var item = $('<li role="listitem">');
            item.append($('<button>').text(Mediasite.Player.Localization.Common.Chapter + ' ' + (i + 1)).click(function () { _events.fire(_eventNames.ChapterChanged, i + 1); }));
            item.append($('<div>').text(presentation.Chapters[i].Text + ' ' + getDisplayFromDuration(presentation.Chapters[i].Time)));
            $('#chapterList').append(item);
        });

        $.each(presentation.Links, function (i) {
            var item = $('<li role="listitem"><a href="' + presentation.Links[i].Url + '" target="new" title="' + presentation.Links[i].Url + '">' + presentation.Links[i].Description + '</a></li>');
            $('#linkList').append(item);
        });

        if (!modelPresentation.PollingEnabled || !modelPresentation.PollingLocation) {
            $('#pollArea').hide();
        }
        else {
            var pollUrl = modelPresentation.PollingLocation;
            $('#pollLink').text(Mediasite.Player.Localization.Buttons.Polls).attr("href", pollUrl).attr("target", "_offsite");
        }

        if (!modelPresentation.ForumEnabled) {
            $('#questionForm').hide();
        }
        else {
            $('#questionSubmit').click(function () { sendQuestion(); });
            $('#questionUseCurrentTime').click(function () { $('#questionTime').val(getShortDisplayFromDuration(currentPosition)); });
        }

        if (!modelPresentation.SharingEnabled) {
            $('#sendEmailForm').hide();
        }
        else {
            fireClickCommand(Mediasite.Player.ClickCommand.OpenEmail);
            $('#sendEmailSubmit').click(function () { sendEmail(); });
            $('#sendEmailUseCurrentTime').click(function () { $('#sendEmailTime').val(getShortDisplayFromDuration(currentPosition)); updateEmailText(); });
            $('#sendEmailUseClientLink').click(function () { setMailToLink(); });
            $('#sendEmailTime').change(function () { updateEmailText(); });
        }
    };
};