// $Revision: 35$
// $Date: 8/31/2007 5:51:16 PM$
// $Author: Sean Alisea$

function SMS_GadgetMessageView(parent)
{
    // Attributes
    this.m_viewController = parent;
    this.m_mobileNumberControl = null;
    this.m_msgCharsAvailable = null;

    var self = this;

    this.m_slotManager = new SIGSLOT_SlotManager( );

    // SMS_SMSHandler Callbacks
    var onMessageSendSucceeded = function(responseMessage) {self.onMessageSendSucceeded(responseMessage);};
    var onMessageSendFailed = function(statusMessage) {self.onMessageSendFailed(statusMessage);};

    this.m_messageHandler = new SMS_SMSHandler(parent.m_source, parent.m_ver, parent.m_os, onMessageSendSucceeded, onMessageSendFailed);
}

// Prototype -----------------------------------------------------------------------------------------------
SMS_GadgetMessageView.prototype = new SMS_View;

// Constants -----------------------------------------------------------------------------------------------
// DOM element ids.
SMS_GadgetMessageView.prototype.ELEM_ID_VIEWFRAME = 'SEND_ViewFrame';
SMS_GadgetMessageView.prototype.ELEM_ID_PHONE = 'SEND_RecipientPhoneNumber';
SMS_GadgetMessageView.prototype.ELEM_ID_CARRIER = 'SEND_RecipientCarrier';
SMS_GadgetMessageView.prototype.ELEM_ID_COUNTRY = 'SEND_CountryCd';
SMS_GadgetMessageView.prototype.ELEM_ID_MSG = 'SEND_Message';
SMS_GadgetMessageView.prototype.ELEM_ID_SUBMIT = 'SEND_SubmitButton';

// Defaults.
SMS_GadgetMessageView.prototype.ELEM_DEFAULT_PHONE = 'Enter Mobile Number';
SMS_GadgetMessageView.prototype.ELEM_DEFAULT_MSG = 'Type Message';

SMS_GadgetMessageView.prototype.MSG_MAX_DOMESTIC_LENGTH_PER_PART = 158;
SMS_GadgetMessageView.prototype.MSG_MAX_INTL_LENGTH_PER_PART = 160;
SMS_GadgetMessageView.prototype.MSG_MAX_UNICODE_LENGTH_PER_PART = 70;
SMS_GadgetMessageView.prototype.MSG_OVERHEAD_CARRIER = 2;

SMS_GadgetMessageView.prototype.GetSlotManager = function( )
{
    return this.m_slotManager;
};

// Init -----------------------------------------------------------------------------------------------------
SMS_GadgetMessageView.prototype.init = function()
{
    this.m_mobileNumberControl = new SMS_MobileNumberControl( this.ELEM_ID_COUNTRY, this.ELEM_ID_PHONE );

    this.m_mobileNumberControl.GetNumberFieldGainFocusSignal( ).Connect( this, "recipientPhoneNumber_onFocus" );
    this.m_mobileNumberControl.GetNumberFieldLoseFocusSignal( ).Connect( this, "recipientPhoneNumber_onBlur" );
    this.m_mobileNumberControl.GetCountryPullDownChangeSignal( ).Connect( this, "checkFields" );

    // Set defaults.
    this.setTextInputPrompt(this.ELEM_ID_PHONE, this.ELEM_DEFAULT_PHONE);
    this.setDropdownPrompt(this.ELEM_ID_COUNTRY);
    this.setDropdownPrompt(this.ELEM_ID_CARRIER);
    this.setTextInputPrompt(this.ELEM_ID_MSG, this.ELEM_DEFAULT_MSG);

    // By default set the text area length to the max allowable for 1 message part, US or Intl --> 160.
   this.setMessageTextAreaLength(this.MSG_MAX_INTL_LENGTH_PER_PART);
}

// Display -------------------------------------------------------------------------------------------------
SMS_GadgetMessageView.prototype.display = function()
{
    // Set defaults.
    this.setTextInputPrompt(this.ELEM_ID_PHONE, this.ELEM_DEFAULT_PHONE);
    this.setDropdownPrompt(this.ELEM_ID_COUNTRY);
    this.setDropdownPrompt(this.ELEM_ID_CARRIER);
    this.setTextInputPrompt(this.ELEM_ID_MSG, this.ELEM_DEFAULT_MSG);

    // Clean the counter text.
    this.setCharCntLabel("");

    // Display the carrier dropdown?
    if (SESSION.getVal(Session_Key.WX_SHOW_CARRIERS) == 0)
    {
        this.getElement("SEND_CarrierRow").style.display = "none";
    }
    else
    {
        // Try table-row value, which works well for Firefox in this context.
        // It will throw an exception for IE, and that will be caught and the block
        // value will be used.
        try
        {
            this.getElement("SEND_CarrierRow").style.display = 'table-row';
        }
        catch (e)
        {
            this.getElement("SEND_CarrierRow").style.display = 'block';
        }
    }

    // Display the parent DIV.
    this.displayElement(this.ELEM_ID_VIEWFRAME);
}

SMS_GadgetMessageView.prototype.hide = function()
{
    this.hideElement(this.ELEM_ID_VIEWFRAME);
}

SMS_GadgetMessageView.prototype.disableForm = function()
{
    this.disableElement(this.ELEM_ID_COUNTRY);
    this.disableElement(this.ELEM_ID_PHONE);
    this.disableElement(this.ELEM_ID_CARRIER);
    this.disableElement(this.ELEM_ID_MSG);
    this.disableElement(this.ELEM_ID_SUBMIT);
    this.setCursorWait();
}

SMS_GadgetMessageView.prototype.enableForm = function()
{
    this.enableElement(this.ELEM_ID_COUNTRY);
    this.enableElement(this.ELEM_ID_PHONE);
    this.enableElement(this.ELEM_ID_CARRIER);
    this.enableElement(this.ELEM_ID_MSG);
    this.enableElement(this.ELEM_ID_SUBMIT);
    this.setCursorDefault();
}

SMS_GadgetMessageView.prototype.checkFields = function( )
{
    try
    {
        this.updateInputStyle( this.ELEM_ID_PHONE, this.ELEM_DEFAULT_PHONE );

        if ( this.updateInputStyle( this.ELEM_ID_MSG, this.ELEM_DEFAULT_MSG ) )
        {
            this.setCharCntLabel("");
        }

        if ( this.m_mobileNumberControl.GetComboBox( ).GetSelectedIndex( ) == 0 )
        {
            this.setEmptyInputStyle( this.ELEM_ID_COUNTRY );
            return;
        }

        this.setNonEmptyInputStyle( this.ELEM_ID_COUNTRY );

        // If the user max's-out the entry while a non-NANP country is selected, then switches to a
        // a NANP country, then we may be left with a few characters that will be over the limit.
        // We then need a nice way to put the kibosh on entry.
        // Conversely if they switch from Intl to NANP, we need to let them know more entry
        // is allowed.
        if (this.getMessage() != this.ELEM_DEFAULT_MSG)
        {
            var chars = this.getMessage().length;
            var availableChars = this.charsAvailable();

            if (chars > availableChars)
            {
                this.setMessage(this.getMessage().substring(0, availableChars));
                this.setStatusMsgError('You have exceeded the message size limit of ' + availableChars + ' characters.  The message has been truncated.');
                this.setCharCntLabel('0 characters remaining');
            }
            else if (chars == availableChars)
            {
                this.setCharCntLabel('0 characters remaining');
            }
            else if ((chars < availableChars) && ((availableChars - chars) <= 25))
            {
                this.setStatusMsgInfo('You now have ' + (availableChars - chars) + ' additional characters remaining for entry.');
                this.setCharCntLabel((availableChars - chars) + ' characters remaining');
            }
        }
    }
    catch ( e )
    {
        EX_ASSERT_NO_EXCEPTIONS( e, "SMS_GadgetMessageView::checkFields( )" );
    }
}

SMS_GadgetMessageView.prototype.getRecipientCarrierId = function()
{
    return this.getElement(this.ELEM_ID_CARRIER).options[this.getElement(this.ELEM_ID_CARRIER).selectedIndex].value;
}

SMS_GadgetMessageView.prototype.selectRecipientCarrierId = function()
{
    this.getElement(this.ELEM_ID_CARRIER).focus();
}

SMS_GadgetMessageView.prototype.selectPhoneNumber = function()
{
    this.getElement(this.ELEM_ID_PHONE).focus();
    this.getElement(this.ELEM_ID_PHONE).select();
}

SMS_GadgetMessageView.prototype.getMessage = function()
{
    return this.getElement(this.ELEM_ID_MSG).value;
}

SMS_GadgetMessageView.prototype.setMessage = function(val)
{
    this.getElement(this.ELEM_ID_MSG).value = val;
}

SMS_GadgetMessageView.prototype.selectMessage = function()
{
    this.getElement(this.ELEM_ID_MSG).focus();
    this.getElement(this.ELEM_ID_MSG).select();
}

SMS_GadgetMessageView.prototype.setCharCntLabel = function(val) {
    this.getElement('SEND_CharCnt').innerHTML = val;
}

SMS_GadgetMessageView.prototype.getValidatedNumber = function( )
{
    var numberValidationData = this.m_mobileNumberControl.GetValidatedNumber( );
    
    if ( ! numberValidationData.ERROR_MESSAGE )
    {
        return numberValidationData.PHONE_NUMBER;
    }

    this.setStatusMsgError( numberValidationData.ERROR_MESSAGE );
    
    this.enableForm();

    this.selectPhoneNumber( );

    return null;
}


SMS_GadgetMessageView.prototype.handleMessageSend = function()
{
    try
    {
        this.m_mobileNumberControl.OnFormSubmit( );

        this.disableForm();

        var validatedNumber = this.getValidatedNumber( );

        if ( validatedNumber === null )
        {
            return;
        }

        // Get and validate message
        var message = this.getMessage( );

        if ( message.length > this.charsAvailable( ) )
        {
			this.enableForm();
            // Selecting the message text will cause the checkFields() function to fire, which
            // will display an error message.            
            this.selectMessage();
            return;
        }

        if ( ( message.replace( /^\s+|\s+$/g, "" ).length == 0 ) ||
             ( this.getElement( this.ELEM_ID_MSG ).style.fontStyle == "italic" ) )
        {
            this.setStatusMsgError( "Please type a message." );
            this.enableForm( );
            this.setTextInputPrompt( this.ELEM_ID_MSG, this.ELEM_DEFAULT_MSG );
            this.selectMessage( );
            return;
        }

        // Validate carrier
        if ( validatedNumber.GetCountryCode( ) == CMD_COUNTRY_CODE_NANP &&
             ( SESSION.getVal( Session_Key.WX_SHOW_CARRIERS ) == 1 ) &&
             ( this.getElement( this.ELEM_ID_CARRIER ).options[0].selected == true ) )
        {
            this.setStatusMsgError( "Please select the recipient's carrier." );
            this.enableForm();
            this.selectRecipientCarrierId( );

            this.bruteForceSelectElement( this.ELEM_ID_PHONE );
            this.bruteForceSelectElement( this.ELEM_ID_MSG );

            return;
        }

        var recipientCarrier = this.getRecipientCarrierId( );
        if ( validatedNumber.GetCountryCode( ) != CMD_COUNTRY_CODE_NANP )
        {
            // Carrier is always '-1' for Intl recipients.
            recipientCarrier = '-1';
        }
        // Carrier is always '0' for NANP recipients if the showCarriers param is in the OFF state.
        else if ( SESSION.getVal( Session_Key.WX_SHOW_CARRIERS ) == 0 )
        {
            recipientCarrier = '0';
        }

        this.setStatusMsgInfo("Sending message...please wait...");

        this.m_messageHandler.sendSMS( VM_GetPreference( PREF_KEY_ACCOUNT ),
                                       VM_GetPreference( PREF_KEY_U_STRING ),
                                       validatedNumber.GetFullyQualifiedString( ),
                                       recipientCarrier,
                                       '0', // sendFromPreference
                                       message );
    }
    catch ( e )
    {
        EX_ASSERT_NO_EXCEPTIONS( e, "SMS_GadgetMessageView.prototype.handleMessageSend()" );
    }
}

SMS_GadgetMessageView.prototype.message_onKeyUp = function()
{
    var field = this.getElement(this.ELEM_ID_MSG);
    var charsRemaining = this.charsAvailable() - field.value.length;

    if (charsRemaining < 0)
    {
        field.value = field.value.substring(0, this.charsAvailable());
        this.setCharCntLabel("0 characters remaining");
        this.setStatusMsgError("You have reached the message size limit.");
    }
    else if (charsRemaining <= 25)
    {
        this.setStatusMsgInfo("");
        this.setCharCntLabel(charsRemaining + " characters remaining");
    }
    else
    {
        this.setStatusMsgInfo("");
        this.setCharCntLabel("");
    }
}

SMS_GadgetMessageView.prototype.charsAvailable = function ()
{
    var totalCharsAvailable;
    var serverCalculatedBodyOverhead;
    var carrierOverhead;
    var returnAddressLength;

    // As of this release of the gadget m_maxSMSParts is still always set to 1.
    var maxSMSParts = 1; //SESSION.getVal(Session_Key.WX_MAX_SMS_PARTS);

    // Calculate total chars available and the total characters reserved by the server based on the recipient type.
    if (this.isRecipientNANP())
    {
        // NANP recipient.
        totalCharsAvailable = this.MSG_MAX_DOMESTIC_LENGTH_PER_PART * maxSMSParts;

        // Additional overhead is calculated by the server and will be subtracted from total chars available.
        serverCalculatedBodyOverhead = SESSION.getVal(Session_Key.WX_SMS_BODY_OH);
        carrierOverhead = this.MSG_OVERHEAD_CARRIER;
    }
    else
    {
        // Intl recipient.
        // Test for Unicode characters.  A different message length is stipulated when Unicode characters are present because they require more space.
        if (this.messageRequiresUnicodeEncoding(this.getMessage()))
        {
            totalCharsAvailable = this.MSG_MAX_UNICODE_LENGTH_PER_PART * maxSMSParts;
        }
        else
        {
            totalCharsAvailable = this.MSG_MAX_INTL_LENGTH_PER_PART * maxSMSParts;
        }

        // The server doesn't calculate any additional overhead for international recipients, so simply set that to zero.
        serverCalculatedBodyOverhead = 0;
        carrierOverhead = 0;
    }

    // Calculate additional overhead for reply-to address based on the sender type.
    if (this.isSenderNANP())
    {
        // NANP sender.

        // Return address for NANP senders = phone number length + max provider domain name length (23)

        // Get sender's phoneNumber from the stored preferences.
        var nanpSenderPhone = SMS_MobileNumberControlPersistentState.prototype.CreateFromString( VM_GetPreference( PREF_KEY_SENDER_MOBILE ) );

        if ( nanpSenderPhone.IsEmpty( ) )
        {
            // Unable to get stored preference value.  Use the default min of 10 + max provider domain name length (23);
            returnAddressLength = 33;
        }
        else
        {
            returnAddressLength = nanpSenderPhone.GetNumberString( ).length + 23;
        }
    }
    else
    {
        // Intl sender.
        // Return address length is set to zero.
        returnAddressLength = 0;
    }

    // Calculate total overhead.
    var totalOverhead = serverCalculatedBodyOverhead + carrierOverhead  + returnAddressLength;

    return totalCharsAvailable - totalOverhead;
}

SMS_GadgetMessageView.prototype.messageRequiresUnicodeEncoding = function(message)
{
    if (typeof GSM_ALPHABET == "undefined")
    {
        GSM_ALPHABET = new Array( 64,163,36,165,232,233,249,236,242,216,248,197,229,95,94,123,125,92,91,126,93,124,198,230,223,201,32,33,34,35,164,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,161,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,196,214,209,220,167,191,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,228,246,241,252,224,231,10,12,13 );
    }

    // Workaround Safari bug, check the code of every character.
    var numChars = message.length;

    var unicodeNeeded = false;
    var i = 0;
    for ( i = 0; i < numChars; i++ )
    {
        var currentCharCode = message.charCodeAt( i );

        var charIsGsm = false;
        var j = 0;
        for ( j = 0; j < GSM_ALPHABET.length; j++ )
        {
            if ( currentCharCode == GSM_ALPHABET[j] )
            {
                charIsGsm = true;
                break;
            }
        }

        if ( ! charIsGsm )
        {
            unicodeNeeded = true;
            break;
        }
    }

    return unicodeNeeded;
}

SMS_GadgetMessageView.prototype.isRecipientNANP = function()
{
    return this.m_mobileNumberControl.GetCountryCode( ) == CMD_COUNTRY_CODE_NANP;
}

SMS_GadgetMessageView.prototype.isRecipientInternational = function()
{
    return this.m_mobileNumberControl.GetCountryCode( ) != CMD_COUNTRY_CODE_NANP;
}

SMS_GadgetMessageView.prototype.isSenderNANP = function()
{
    return SESSION.getVal(Session_Key.WX_PHONE_CC) == CMD_COUNTRY_CODE_NANP;
}

SMS_GadgetMessageView.prototype.setMessageTextAreaLength = function(val)
{
    this.getElement(this.ELEM_ID_MSG).setAttribute("maxlength", val);
}

SMS_GadgetMessageView.prototype.recipientPhoneNumber_onClick = function()
{
    this.flipStyle(this.ELEM_DEFAULT_PHONE, this.ELEM_ID_PHONE);
    this.getElement(this.ELEM_ID_PHONE).select();
}

SMS_GadgetMessageView.prototype.recipientPhoneNumber_onFocus = function()
{
	this.checkFields();
    this.getElement(this.ELEM_ID_PHONE).select();
}

SMS_GadgetMessageView.prototype.recipientPhoneNumber_onBlur = function()
{
    this.updateInputStyle( this.ELEM_ID_PHONE, this.ELEM_DEFAULT_PHONE );
}

SMS_GadgetMessageView.prototype.recipientPhoneNumber_onKeyDown = function(evt)
{
    this.onKeyDown(evt);
    this.flipStyle(this.ELEM_DEFAULT_PHONE, this.ELEM_ID_PHONE);
}

SMS_GadgetMessageView.prototype.countryCd_onKeyDown = function(evt)
{
    this.onKeyDown(evt);
}

SMS_GadgetMessageView.prototype.carrierId_onFocus = function()
{
    this.checkFields();
}

SMS_GadgetMessageView.prototype.carrierId_onChanged = function(elem)
{
    var carrierId = this.getRecipientCarrierId();

    if ((elem.options[0].selected == true) || (elem.value == '999'))
    {
        elem.options[0].selected = true;
        elem.className = 'inputPrompt';
    }
    else
    {
        elem.className = 'input';
    }
}

SMS_GadgetMessageView.prototype.countryCd_onChanged = function( comboBox )
{
    // Reset status messages.
    this.setStatusMsgInfo('');
    this.setCharCntLabel('');

    var selectedCountryCode = comboBox.GetSelectedMenuItem( ).m_countryData.m_countryCode;

    if ( comboBox.GetSelectedIndex( ) === 0 ||
         selectedCountryCode === CMD_COUNTRY_CODE_CONTROL_ID )
    {
        this.setDropdownPrompt( this.ELEM_ID_COUNTRY );
        return;
    }

    var elem = this.getElement( this.ELEM_ID_COUNTRY );
    elem.style.color = 'black';
    elem.style.fontStyle = 'normal';

    if ( SESSION.getVal( Session_Key.WX_SHOW_CARRIERS ) != 1 )
    {
        return;
    }

    // Hide carrier dropdown in International mode
    if ( selectedCountryCode != CMD_COUNTRY_CODE_NANP )
    {
        this.hideElement( "SEND_CarrierRow" );
        return;
    }

    // Try table-row value, which works well for Firefox in this context.
    // It will throw an exception for IE, and that will be caught and the block
    // value will be used.
    try
    {
        this.getElement("SEND_CarrierRow").style.display = 'table-row';
    }
    catch (e)
    {
        this.getElement("SEND_CarrierRow").style.display = 'block';
    }
}

SMS_GadgetMessageView.prototype.message_onFocus = function()
{
    this.checkFields();
    this.selectMessage();
}

SMS_GadgetMessageView.prototype.message_onClick = function()
{
    this.flipStyle(this.ELEM_DEFAULT_MSG, this.ELEM_ID_MSG);
}

SMS_GadgetMessageView.prototype.message_onKeyDown = function(evt)
{
    this.flipStyle(this.ELEM_DEFAULT_MSG, this.ELEM_ID_MSG);
}

SMS_GadgetMessageView.prototype.sendSubmitButton_onClick = function()
{
    try
    {
        this.handleMessageSend();
    }
    catch ( e )
    {
        EX_Log( "SMS_GadgetMessageView.prototype.sendSubmitButton_onClick():\n" + e.message );
    }
}

SMS_GadgetMessageView.prototype.archiveLink_onFocus = function()
{
    this.checkFields();
}

SMS_GadgetMessageView.prototype.accountLink_onFocus = function()
{
    this.checkFields();
}

SMS_GadgetMessageView.prototype.logoutLink_onFocus = function()
{
    this.checkFields();
}

SMS_GadgetMessageView.prototype.logoutLink_onClick = function()
{
    this.m_viewController.logOff();
}

SMS_GadgetMessageView.prototype.feedbackLink_onFocus = function()
{
    this.checkFields();
}

SMS_GadgetMessageView.prototype.helpLink_onFocus = function()
{
    this.checkFields();
}

SMS_GadgetMessageView.prototype.onKeyDown = function(evt)
{
    try
    {
        if (this.keyDownIsEnter(evt))
        {
            this.handleMessageSend();
        }
    }
    catch ( e )
    {
        EX_Log( "SMS_GadgetMessageView.prototype.onKeyDown():\n" + e.message );
    }
}

SMS_GadgetMessageView.prototype.onMessageSendSucceeded = function(responseMessage)
{
    try
    {
        this.enableForm();

        switch (responseMessage.m_status)
        {
            case MSG_ResponseStatus.SUCCESS:
            {
                // Re-set fields.
                this.setStatusMsgInfo(responseMessage.m_statusMsg);

                this.setTextInputPrompt(this.ELEM_ID_MSG, this.ELEM_DEFAULT_MSG);

                this.setCharCntLabel("");

                break;
            }

            default:
            {
                // Check the server status message.  Display if one is provided; otherwise,
                // use a generic default.
                var alertMessage = "Sorry, failed to send message. Please try again.";

                if (responseMessage.m_statusMsg != null && responseMessage.m_statusMsg.length != 0)
                {
                    alertMessage = responseMessage.m_statusMsg;
                }

                this.setStatusMsgError(alertMessage);

                break;
            }
        }
    }
    catch (e)
    {
        this.setStatusMsgError("Application exception.");
    }
}

SMS_GadgetMessageView.prototype.onMessageSendFailed = function(statusMessage)
{
    try
    {
        this.enableForm();
        this.setStatusMsgError(statusMessage);
    }
    catch (e)
    {
        this.setStatusMsgError("Application exception.");
    }
}
