/// <reference path="../ScriptReference/jquery-1.7.1-vsdoc.js"/>

/*
* jQuery UI PlayerInvitePanel
*
* Depends:
*   jquery.ui.core.js
*   jquery.ui.widget.js
*   jquery.iscroll.js
*   Mediasite.Player.Localization.js
*   Mediasite.Player.DisplayMessage (dialog wrapper widget)
*/

(function ($) {
    $.widget("ui.playerinvitepanel", {
        options: {
            ids: {
                header: 'ui-playerinvitepanel-header',
                scroll: 'ui-playerinvitepanel-scroll',
                scrollWrapper: 'ui-playerinvitepanel-scroll-wrapper',
                fromField: 'ui-playerinvitepanel-from',
                toField: 'ui-playerinvitepanel-to',
                toSeparator: 'ui-playerinvitepanel-toSeparator',
                subjectField: 'ui-playerinvitepanel-subject',
                messageField: 'ui-playerinvitepanel-message',
                timeCheckBox: 'ui-playerinvitepanel-time-checkbox',
                timeField: 'ui-playerinvitepanel-time',
                timeFormat: 'ui-playerinvitepanel-time-format',
                timeLabel: 'ui-playerinvitepanel-timeLabel',
                submitArea: 'ui-playerinvitepanel-submit',
                sendButton: 'ui-playerinvitepanel-sendBtn',
                modalMask: 'ui-playerinvitepanel-modalmask',
                msgDialog: 'ui-playerinvitepanel-message-dialog',
                useClientLink: 'ui-playerinvitepanel-useclient'
            },
            classes: {
                panel: 'ui-playerinvitepanel',
                form: 'ui-playerinvitepanel-form',
                header: 'panel-header',
                inputStretch: 'input-stretch',
                inputReadOnly: 'input-readonly',
                modalMask: 'panel-modal-mask',
                toSeparator: 'toseparator'
            },
            subject: {
                maxLength: 512
            },
            message: {
                cols: 20,
                rows: 10
            },
            labelMargin: 115,
            currentPosition: 0,
            presentation: null,
            onSendEmail: null,
            dismissFunction: null,
            scrollbarColor: 'rgba(255,255,255,0.5)',
            url: window.location.href,
            window: window,
            javascriptResize: true,
            msgDialogWidth: undefined
        },

        _setOption: function (key, value) {
            var self = this,
                o = self.options;

            o[key] = value;

            //disable time checkbox if live
            if (key === 'presentation' && o.presentation.PlayStatus != "OnDemand") {
                self.hideTimeData();
            }
            //

            // update time field
            if (key === 'currentPosition') {
                $('#' + o.ids.timeField, self.element).val(Mediasite.Player.TimeHelper.getDisplayFromDuration(o.currentPosition, true));
                self._updateEmailText();
            }
        },

        _create: function () {
            var self = this,
                o = self.options;
            self._msgDialogInterval = 0;
            self.element.addClass(o.classes.panel);
            var markup =
                '<p id="' + o.ids.header + '" class="' + o.classes.header + '">' + Mediasite.Player.Localization.Buttons.Email + '</p>' +
                    '<div id="' + o.ids.scrollWrapper + '">' +
                        '<div id="' + o.ids.scroll + '">' +
                            '<form class="' + o.classes.form + '">' +
                                '<p><label for="' + o.ids.fromField + '">' + Mediasite.Player.Localization.Email.From + '</label><input type="text" name="from" id="' + o.ids.fromField + '" class="' + o.classes.inputStretch + ' ' + o.classes.inputReadOnly + '" readonly /></p>' +
                                '<p><label for="' + o.ids.toFiled + '"> * ' + Mediasite.Player.Localization.Email.To + '</label><input type="text" name="to" id="' + o.ids.toField + '"  class="' + o.classes.inputStretch + '" /><br />' +
                                '<span id="' + o.ids.toSeparator + '" class="' + o.classes.toSeparator + '">' + Mediasite.Player.Localization.Email.ToSeparator + '</span></p>' +
                                '<p><label for="' + o.ids.subjectField + '"> * ' + Mediasite.Player.Localization.Email.Subject + '</label><input type="text" name="subject" id="' + o.ids.subjectField + '" maxlength="' + o.subject.maxLength + '" class="' + o.classes.inputStretch + '" /></p>' +
                                '<p><label id="' + o.ids.timeLabel + '" for="' + o.ids.timeCheckBox + '">' + Mediasite.Player.Localization.Email.Time + '</label><input type="checkbox" name="timeCheckbox" id="' + o.ids.timeCheckBox + '"/><input type="text" name="time" id="' + o.ids.timeField + '" /><span id="' + o.ids.timeFormat + '">' + Mediasite.Player.Localization.Email.TimeFormat + '</span></p>' +
                                '<p><label for="' + o.ids.messageField + '"> * ' + Mediasite.Player.Localization.Email.Message + '</label><textarea name="message" id="' + o.ids.messageField + '" rows="' + o.message.rows + '" cols="' + o.message.cols + '" class="' + o.classes.inputStretch + '"></textarea></p>' +
                                '<p id="' + o.ids.submitArea + '"><a id="' + o.ids.useClientLink + '" href="#">' + Mediasite.Player.Localization.Email.UseClient + '</a> <input id="' + o.ids.sendButton + '" type="submit" value="' + Mediasite.Player.Localization.Common.Send + '" /></p>' +
                                '<p><span class="requiredField">* ' + Mediasite.Player.Localization.Common.RequiredField + '</span></p>' +
                            '</form>' +
                        '</div>' +
                    '</div>' +
                    '<div id="' + o.ids.modalMask + '" class="' + o.classes.modalMask + '">' + '</div>';
            self.divMarkup = $(markup).appendTo(self.element);

            $('#' + o.ids.useClientLink, self.element).on('mousedown', function (e) {
                self._updateEmailLink();
            });

            $('#' + o.ids.useClientLink, self.element).on('click', function (e) {
                if (e.which === 1 && !e.metaKey && !e.shiftKey && !e.ctrlKey && !e.shiftKey) {
                    e.preventDefault();
                    self._useClientEmail();
                }
            });

            var submitForm = function (e) {
                e.preventDefault();
                self._sendInvite();
            };
            $('form', self.element).bind('submit', submitForm);
            $('#' + o.ids.sendButton, self.element).bind('click', submitForm);
            self._overlayState(false);
            $('#' + o.ids.timeCheckBox, self.element).change(function () { self._updateEmailText(); });
            $('#' + o.ids.timeField, self.element).attr('disabled', true).change(function () { self._updateEmailText() });

            if (o.javascriptResize) {
                $(o.window).resize(function () {
                    self.updateLayout();
                });
            }
        },

        hideTimeData: function () {
            var o = this.options;
            $('#' + o.ids.timeCheckBox, self.element).hide();
            $('#' + o.ids.timeField, self.element).hide();
            $('#' + o.ids.timeFormat, self.element).hide();
            $('#' + o.ids.timeLabel, self.element).hide();
        },

        updateLayout: function () {
            var self = this,
                o = self.options;

            // stretch out input fields
            $('.input-stretch', self.element).width(self.element.innerWidth() - o.labelMargin);
            $('#' + o.ids.messageField, self.element).width(self.element.innerWidth() - o.labelMargin - 2); // <TEXTAREA> is weird


            var $scrollWrapper = $('#' + o.ids.scrollWrapper, self.element);
            var availableHeight = self.element.height(); // Start with panel's inner height
            // Subtract height of pertinent siblings
            availableHeight -= $('#' + o.ids.header, self.element).outerHeight(true);
            // availableHeight is now space alloted for the scroll wrapper
            // Allow for scroll wrapper's padding and margin
            availableHeight -= parseInt($scrollWrapper.css('margin-top'), 10) || 0;
            availableHeight -= parseInt($scrollWrapper.css('margin-bottom'), 10) || 0;
            availableHeight -= parseInt($scrollWrapper.css('padding-top'), 10) || 0;
            availableHeight -= parseInt($scrollWrapper.css('padding-bottom'), 10) || 0;

            availableHeight = availableHeight > 0 ? availableHeight : 20; // just in case

            $scrollWrapper.height(availableHeight);

            // refresh iscroll
            $('#' + o.ids.scroll, self.element).iscroll({ scrollbarColor: o.scrollbarColor });
        },

        destroy: function () {
            var o = this.options;

            this.element.removeClass(o.classes.panel);
            this.divMarkup.remove();
        },

        _init: function () {
            var self = this,
                o = self.options;

            //hide time controls and labels alltogether if live
            if (o.presentation != null && o.presentation.PlayStatus != "OnDemand") {
                self.hideTimeData();
            }

            if (o.javascriptResize) {
                this.updateLayout();
            }
        },

        updateEmailInvite: function (emailData) {
            var self = this,
                o = self.options;

            $('#' + o.ids.subjectField, self.element).val(emailData["Subject"]);
            $('#' + o.ids.messageField, self.element).val(emailData["Message"]);
            $('#' + o.ids.fromField, self.element).val(emailData["FromAddress"]);
            $('#' + o.ids.toField, self.element).val("");
            $('#' + o.ids.useClientLink, self.element).attr('href', this._getShareLink());

            if (emailData["UseServerForSMTP"]) {
                $('#' + o.ids.timeField, self.element).val(Mediasite.Player.TimeHelper.getDisplayFromDuration(o.currentPosition, true));
                self._updateEmailText();
                return false;
            } else {
                self._useClientEmail();
            }
        },

        _updateEmailLink: function() {
            var self = this,
                o = self.options;
                
            $('#' + o.ids.useClientLink, self.element).attr('href', this._getShareLink());
        },

        _updateEmailText: function () {
            var self = this,
                o = self.options;

            var linkRegEx = /\bhttps?:\/\/[-A-Z0-9+&@\/%=~_|!:,.;]+\/Play\/[-A-Z0-9+&@#\/%?=~_|!:,.;]+[-A-Z0-9+&@#\/%=~_|]/ig;
            var startTimeMS = 0;

            if ($('#' + o.ids.timeCheckBox, self.element).is(':checked')) {
                startTimeMS = Mediasite.Player.TimeHelper.getDurationFromDisplay($('#' + o.ids.timeField, self.element).val());
                $('#' + o.ids.timeField, self.element).removeAttr('disabled');
            } else {
                $('#' + o.ids.timeField, self.element).attr('disabled', true)
            }

            var messageText = $('#' + o.ids.messageField, self.element).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;
            }

            $('#' + o.ids.messageField, self.element).val(messageText.replace(linkRegEx, playLink));
        },

        sendInviteComplete: function (success, message) {
            var self = this,
                o = self.options;
            var title = Mediasite.Player.Localization.Email.SendSuccessTitle;
            var dismissHandler;

            if (success) {
                dismissHandler = function () {
                    $(self).unbind();

                    if (jQuery.isFunction(o.dismissFunction)) {
                        o.dismissFunction();
                    }
                };
            } else {
                title = Mediasite.Player.Localization.Email.SendErrorTitle;
            }

            self._displayMessage(title, message, dismissHandler);
        },

        _getShareLink: function () {
            var self = this, o = self.options;
            var escapeAndUriEncode = Mediasite.Urls.EscapeForMailto;

            var link = "mailto:" + escapeAndUriEncode($('#' + o.ids.toField, self.element).val()) + "?subject=" + escapeAndUriEncode($('#' + o.ids.subjectField, self.element).val()) + "&body=" + escapeAndUriEncode($('#' + o.ids.messageField, self.element).val());
            if (link.length > 1000) {
                link = "mailto:" + escapeAndUriEncode($('#' + o.ids.toField, self.element).val()) + "?subject=" + escapeAndUriEncode($('#' + o.ids.subjectField, self.element).val()) + "&body=" + escapeAndUriEncode(o.url);
            }

            return link;
        },

        _useClientEmail: function (e) {
            var self = this,
                o = self.options;

            if (jQuery.isFunction(o.dismissFunction)) {
                o.dismissFunction();
            }

            var link = self._getShareLink();
            if (Mediasite.BrowserDetect.Chrome() && !Mediasite.BrowserDetect.ChromeAndroid()) {
                var emailWindow = window.open(link);
                setTimeout(function() { emailWindow && emailWindow.close(); }, 1);
            } else {
                window.location = link;
            }
        },

        _sendInvite: function () {
            var self = this,
                o = self.options;

            var recipients = [];
            $.each($('#' + o.ids.toField, self.element).val().split(";"), function (i, val) {
                if ($.trim(val).length > 0) {
                    recipients.push($.trim(val));
                }
            });

            var from = $.trim($('#' + o.ids.fromField, self.element).val());

            if (validateEmailMessage(from, recipients)) {
                var invite = {
                    ToAddresses: recipients,
                    FromAddress: from,
                    Subject: $('#' + o.ids.subjectField, self.element).val(),
                    MessageBody: $('#' + o.ids.messageField, self.element).val(),
                    Time: Mediasite.Player.TimeHelper.getDurationFromDisplay($('#' + o.ids.timeField, self.element).val())
                };

                if (jQuery.isFunction(o.onSendEmail)) {
                    o.onSendEmail(invite);
                }
            }

            function validateEmailAddress(address) {
                var emailRegEx = /^[A-Z0-9.'_%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$/i;
                return emailRegEx.test(address);
            }

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

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

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

                //subject/message cant be blank
                if ($('#' + o.ids.subjectField, self.element).val() == "" || $.trim($('#' + o.ids.subjectField, self.element).val()) == "") {
                    errorString += "<br/> - " + Mediasite.Player.Localization.Email.SubjectRequired;
                }
                if ($('#' + o.ids.messageField, self.element).val() == "" || $.trim($('#' + o.ids.messageField, self.element).val()) == "") {
                    errorString += "<br/> - " + Mediasite.Player.Localization.Email.MessageRequired;
                }

                var timeIsValid = true;

                // #region Validate inputted time, if necessary
                if (o.presentation != null && o.presentation.PlayStatus == "OnDemand") { // Is this on-demand? (Can't link to a specific time for live)
                    var $timeCheckbox = $('#' + o.ids.timeCheckBox, self.element);
                    if ($timeCheckbox.length > 0 && $timeCheckbox[0].checked) { // Is the "link to this time?" checkbox checked?
                        // Is time valid (value exists and is within presentation length)?
                        if ($('#' + o.ids.timeField, self.element).val().length < 1 || Mediasite.Player.TimeHelper.getDurationFromDisplay($('#' + o.ids.timeField, self.element).val()) > o.presentation.Duration) {
                            timeIsValid = false;
                            errorString += "<br/> - " + Mediasite.Player.Localization.Email.TimeInvalid;
                        }

                        // Is time formatted correctly?
                        if (Mediasite.Player.TimeHelper.getDurationFromDisplay($('#' + o.ids.timeField, self.element).val()) == -1) {
                            timeIsValid = false;
                            errorString += "<br/> - " + Mediasite.Player.Localization.Email.TimeFormatError;
                        }
                    }
                }

                if (errors > 0 || valid < 1) {
                    errorString += "<br/> - " + Mediasite.Player.Localization.Email.InviteInvalid;
                }

                if (errorString != "") {
                    self._displayMessage(Mediasite.Player.Localization.Buttons.Email, "<strong>" + Mediasite.Player.Localization.Email.ValidationError + "</strong><br/>" + errorString + "<br/>");
                    return false;
                }

                return true;
            }
        },

        _displayMessage: function (title, message, callback) {

            var self = this,
                o = self.options;

            self._overlayState(true);

            self._killDisplayMessage();
            var messageElement = $('<div id="' + o.ids.msgDialog + '"></div>');
            messageElement.appendTo(self.element);

            var messageOptions =
            {
                title: title,
                message: message,
                allowClose: false,
                dialogClass: 'panelMessage',
                width: o.msgDialogWidth ? o.msgDialogWidth : self.element.innerWidth() - 4,
                modal: false,
                close: function () {
                    self._overlayState(false);
                    if ($.isFunction(callback)) {
                        callback();
                    }
                },
                position:
                {
                    my: "center top",
                    at: "center top+100",
                    of: self.element
                },
                appendTo: self.element
            };
            messageElement.messagedisplay(messageOptions);

            self._msgDialogInterval = setInterval(function () {
                if (!self.element.is(':visible')) {
                    self._overlayState(false);
                    clearInterval(self._msgDialogInterval);
                }
            }, 500);
        },

        _overlayState: function (show) {
            var self = this,
                   o = self.options;

            show ? $('#' + o.ids.modalMask, self.element).show() : $('#' + o.ids.modalMask, self.element).hide();
        },

        _killDisplayMessage: function () {

            var self = this,
                o = self.options;

            var messageElement = $('#' + o.ids.msgDialog, self.element);

            if (messageElement.length > 0) {
                if (messageElement.hasClass('messagedisplayinit')) {
                    messageElement.messagedisplay('destroy');
                }
                messageElement.remove();
            }

        }
    });
})(jQuery);
