/*
Abstract: JavaScript logic for Bulletin Wireless SMS LIVE widget
Version: 1.0
© Copyright 2007, 2008 Bulletin Wireless, Inc. All rights reserved.
*/

var gWidget = new BWWidget();

function DebugLog() {

    this.log = function (msg) {
        console.log(msg);
    }
};

var gDebug = new DebugLog();

function BWWidget() {

    this.lastUpdated = 0;
    this.userName = null;
    this.password = null;
    this.prefsLoaded = false;

    this.accountType = "";
    this.accountBalance = 0;
    this.currencyStr = "";
    this.currentMsgID = null;
    
    this.server = new Rpc();

    this.inbox = [];
    this.sentbox = [];
    this.activeMailbox = "in";
    this.timer = 0;
    this.autoRefreshTimer = 0;
};

BWWidget.prototype.load = function () {

    this.checkProtocol();
    
    this.clearWidget();

    this.loadPreferences();
    if (this.prefsLoaded) {
        this.getMessages("in");
    }

    // this.autoRefreshTimer = setInterval("gWidget.autoGetMessages();", 360000); // Refresh every 10 minutes
};

BWWidget.prototype.logout = function() {
    
    gDebug.log("Logout user: clearing cookie data");
    
    this.setCookieData("BWUser", ""); 
    this.setCookieData("BWPassword", "");
    
    var user = document.getElementById("UserInputField");
    var password = document.getElementById("PasswordInputField");
        
    if (user) {
        user.value = "";
    }
    
    if (password) {
        password.value = "";
    }
    
    this.userName = null;
    this.password = null;
    
	var canvas = document.getElementById("received");
    if (canvas) {
        canvas.innerHTML = "";
    }
    
    canvas = document.getElementById("sent");
    if (canvas) {
        canvas.innerHTML = "";
    }

}

BWWidget.prototype.checkProtocol = function() {

    gDebug.log("URL: " + window.location);
    
    var protocol = window.location.protocol;
    if (protocol != "https:") {
               
        var len = document.URL.length;
        window.location = "https" + document.URL.substr(4, (len - 4));
        gDebug.log("HTTP protocol used, redirecting to HTTPS: " + window.location);
    }
}

BWWidget.prototype.clearWidget = function () {

    var field = document.getElementById("MessageInputField");
    if (field) {
        field.value = "";
    }
     
    field = document.getElementById("DestinationInputField");
    if (field) {
        field.value = "";
    }
};

BWWidget.prototype.backAction = function () {
    this.resetSendButton();
}

BWWidget.prototype.msgKeypress = function () {
    
    var message = document.getElementById("MessageInputField");
    if (message.value.length > 160) {

        // truncate to 160 chars 
        message.value = message.value.substr(0, 160);
    }
}

BWWidget.prototype.savePreferences = function () {

    var updated = false;

    gDebug.log("Saving preferences");

    var user = document.getElementById("UserInputField");
    var password = document.getElementById("PasswordInputField");
        
    if (user && user.value.length > 0) {

        if (user.value != this.userName) {
            this.userName = user.value;
            updated = true;
        }
    }

    if (password && password.value.length > 0) {

        if (password.value != this.password || updated) {
            var hashedPass = b64_sha1(password.value);
            this.password = b64_sha1(user.value + hashedPass);

            gDebug.log("User password hash: " + this.password);
            updated = true;
        }
    }

    var exp = new Date(); 
    var oneYearFromNow = exp.getTime() + (365 * 24 * 60 * 60 * 1000); 
    exp.setTime(oneYearFromNow);
    
    this.setCookieData("BWUser", this.userName, exp); 
    this.setCookieData("BWPassword", encodeURIComponent(this.password), exp);
    
    gDebug.log("Saving cookie: " + document.cookie);

    this.prefsLoaded = true;
};

BWWidget.prototype.loadPreferences = function () {

    var currencyFormatted = function(amount) {

        var i = parseFloat(amount);

        if(isNaN(i)) { i = 0.00; }
        var minus = '';
        if(i < 0) { minus = '-'; }
        i = Math.abs(i);
        i = parseInt((i + .005) * 100);
        i = i / 100;
        s = new String(i);
        if(s.indexOf('.') < 0) { s += '.00'; }
        if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
        s = minus + s;
        return s;
    }
        
    var username, password;
 
    username = this.getCookieData("BWUser");
    password = decodeURIComponent(this.getCookieData("BWPassword"));
    
    if (username != null || username != undefined) {
        this.userName = username;
    }
    if (password != null || password != undefined) {
        this.password = password;
    }

    var field = document.getElementById("UserInputField");
    if (field) {
        field.value = this.userName;
    }

    field = document.getElementById("PasswordInputField");
    if (field) {
        field.value = this.password;
    }

    field = document.getElementById("AccountBalance");
    if (field) {

        if (this.accountType == 'PRE') {
            field.value  = currencyFormatted(this.accountBalance).toString();
        }
        else {
            field.value = "On Account";
        }
    }

    if (this.userName.length > 0 && this.password.length > 0) {
        this.prefsLoaded = true;
    }
};

BWWidget.prototype.getCookieData = function (labelName) {

    var labelLen = labelName.length; 
    // read cookie property only once
    var cookieData = document.cookie; 
    var cLen = cookieData.length; 
    var i = 0; 
    var cEnd;
    
    gDebug.log("Loading cookie data " + cookieData);
    
    while (i < cLen) {
        
        var j = i + labelLen; 
        if (cookieData.substring(i,j) == labelName) { 
        
            cEnd = cookieData.indexOf(";",j); 
            if (cEnd == -1) { 
                cEnd = cookieData.length; 
            } 
            return unescape(cookieData.substring(j+1, cEnd)); 
        } 
        i++; 
    } 
    return ""; 
}; 
    
BWWidget.prototype.setCookieData = function (name, value, expires, path, domain, secure) {
    
    document.cookie= name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
        
    gDebug.log("Setting cookie data: " + document.cookie);        
}


BWWidget.prototype.registerUser = function () {

    window.open('http://www.bulletinonline.net/promo/touch2txt');
};

BWWidget.prototype.showHelp = function () {
	
    var helpWin = window.open('http://www.bulletinmessenger.net/livewidget/guides/touch2txtguide.html');
};

BWWidget.prototype.showPaymentsPage = function () {

    window.open('http://www.bulletinonline.net/user/myAccount.do');   // URL for staging servers
};

BWWidget.prototype.sendMessage = function () {

    var result = false;

    if (! this.promptCredentials()) {
        return false;
    }

    var address = document.getElementById("DestinationInputField").value;
    var message = document.getElementById("MessageInputField").value;

    if (address.length > 0 && message.length > 0) {

        // truncate to 160 chars (why 163 then you ask, good question, - it a safari bug!)
        message = message.substr(0, 163); 

        //Create URL for Http Request
        var url = "https://www.bulletinmessenger.net";
        url += "/api/1/sms/out";
        url += "?userId=" + encodeURIComponent(this.userName);
        url += "&password=" + encodeURIComponent(this.password);
        url += "&to=" + encodeURIComponent(this.trimStr(address));
        url += "&body=" + encodeURIComponent(message);

        gDebug.log("Calling URL: " + url);
        this.server.callback = this.checkCallStatus;

        result = this.server.sendRequest("POST", url, true);

        if (! result) {
            
            window.alert("Send message request failed!");
            gDebug.log("sendMessage() failed " + this.server.httpRequest.statusText);
        }
        else {
            this.clearWidget();
        }
    }
    else {
        window.alert("Destination address and message text cannot be empty");
    }

    return result;
};


BWWidget.prototype.checkCredentials = function() {

	var result = false;
	
	var name = this.userName;
	var pass = this.password;
	
	if ((name != null && name != undefined) && name.length > 0) {
        result = true;
    }
    else {
        result = false;
    }
    if ((pass != null && pass != undefined) && pass.length > 0) {
        result = true;
    }
    else {
        result = false;
    }
    
    if (result) {
        gDebug.log("Checking for credentials: found");
    }
    else {
        gDebug.log("Checking for credentials: NOT FOUND!");        
    }
    
	return result;
};

BWWidget.prototype.promptCredentials = function() {

	var result = this.checkCredentials();
	if (! result) {
		alert("You must enter your Bulletin username & password before using this using this feature");
	}
	return result;
};

BWWidget.prototype.autoGetMessages = function() {

    gDebug.log("Auto check for new messages");

    if (this.checkCredentials()) {
        this.getMessages("in");
    }
};

BWWidget.prototype.loadMailBox = function(mbox) {

	gDebug.log("Loading mailbox " + mbox);

	this.promptCredentials();
	
	if (this.getMessages(mbox)) {
            this.showMailBox(mbox);
	}
};

BWWidget.prototype.getMessages = function(mbox) {

	if (! this.checkCredentials()) {
	
	    gDebug.log("No username & password");
        return false;
	}

    var result = false;
    var feedType = "reply";

    if (mbox == "out") {
        feedType = "out";
    }
    
    this.activeMailbox = mbox;
    
    gDebug.log("Sending request to server for RSS (" + feedType + ") feed");

    var url = "https://www.bulletinmessenger.net";

    url += "/api/2/sms/list";
    url += "?userId=" + encodeURIComponent(this.userName);
    url += "&password=" + encodeURIComponent(this.password);
    url += "&format=rss";
    url += "&type=" + feedType;

    gDebug.log("Calling URL: " + url);
    
    this.server.callback = this.checkMessageResponse;
    result = this.server.sendRequest("GET", url, true);
    if (! result) {
    
        window.alert("Error", "Get messages request to server failed!");
        gDebug.log("getMessages() failed:  " + this.server.httpRequest.status+ " " + this.server.httpRequest.statusText);
        
        if (gErrorChain.length > 0) {
            for (var idx = 0; idx < gErrorChain.length; idx++) {
                gDebug.log("Exception: " + gErrorChain[idx]);
            }
        }
    }

    return result;
};

BWWidget.prototype.checkCallStatus = function () {

    if (gWidget.server.requestComplete) {

        gDebug.log("Server returned status: " + gWidget.server.returnStatus);

        if (gWidget.server.returnStatus == 204 || gWidget.server.returnStatus == 200) {
            
            gWidget.server.callback = null;
            window.alert("Message sent");
        }
        else {

            var message = "Message was not sent ";
            if (gWidget.server.returnStatus) {

                if (gWidget.server.returnStatus == 403) {

                    var address = document.getElementById("DestinationInputField").value;
                    if (address == null) {
                        address = "";
                    }
                    message += ". Message could not be delivered to recipient " + address;
                }
                else if (gWidget.server.returnStatus == 401) {
                    
                    messsage += ", authentication failed. Please check your username and password";
                }
                else {
                    
                    var statusText = gWidget.server.returnStatus.toString();
                    if (statusText) {
                        message += statusText;
                    }
                    if (gWidget.server.returnStatusText) {
                        message += gWidget.server.returnStatusText;
                    }
                }
            }

            window.alert(message);
        }
    }
/*    else {
        this.timer = setInterval("gWidget.checkCallStatus()", 1000);
    }*/
};

BWWidget.prototype.checkMessageResponse = function () {

    gDebug.log("Checking response to feed request");

    if (gWidget.server.requestComplete) {

        gDebug.log("Got returned status: " + gWidget.server.returnStatus);

        if (gWidget.server.returnStatus == 200) {

            gDebug.log("Got rss feed from server");
            gWidget.parseMessageFeed(gWidget.server.getResponse());
        }
        else {

            var message = "Error getting messages";
            if (gWidget.server.returnStatus) {
                
                if (gWidget.server.returnStatus == 401 || gWidget.server.httpRequest.status == 401) {
                    message += ". Please check your username and password";
                }
                else {
                    message += " (" + gWidget.server.returnStatus.toString()  + ") ";
                }
            }
            if (gWidget.server.returnStatusText) {
                message += gWidget.server.returnStatusText
            }
            window.alert(message);
        }
    }
/*    else {
        window.setTimeout("gWidget.checkMessageResponse()", 1000);
    }*/
};

BWWidget.prototype.showMailBox = function(mbox) {

	// default mailbox is in , received messages
    var mailbox = this.inbox;
	var canvas = document.getElementById("received");
	
	if (mbox == "out") {
	
	   	mailbox = this.sentbox;
        canvas = document.getElementById("sent");
    }
    
    this.resetSendButton();

    gDebug.log("Displaying mailbox " + mbox + " " + mailbox.length + " messages ");
    
    if (! canvas) {
        gDebug.log("No canvas to write messages to!");
    }
    canvas.innerHTML = "";

    var label = "From: ";
    var line1, line2;

    if (mbox == "out") {
        label = " To: ";
    }

    if (mailbox.length > 0) {

        for (var idx = 0; idx < mailbox.length; idx++) {

            var msg = mailbox[idx];
            var date = msg.msgDate.substr(6, 2) + "-" + msg.msgDate.substr(3, 2);

            var text = msg.msgText.substr(0, 42);
            if (msg.msgText.length > 42) {
                text += " ...";
            }

            var line = "<li><a href='#message' onclick='gWidget.showMessageDetail(" + idx + ");' >";
            line += "<div class='msgDate'>" + date + "</div>";
            line += "<div class='msgAddress'>" + label + msg.msgAddress + "</div>";
            line += "<div class='msgLine'>" + text + "</div></a></li>"

			canvas.innerHTML += line;
        }
    }
};

BWWidget.prototype.showMessageDetail = function (msgIndex) {

    var mailbox = this.inbox;
    var labelHTML = "From: ";

    if (this.activeMailbox == "out") {
		mailbox = this.sentbox;
        labelHTML = "To: ";
    }
    else {
    
        var newButton = document.getElementById("newMessage");
        if (newButton) {
            
            newButton.innerHTML = "Reply";    
        }
    }

	var msg = mailbox[msgIndex];
	if (msg) {
	
        this.currentMsgID = msgIndex;
    
		var lineColor = "darkgreen";
		if (! gStatusCode.goodStatus(msg.msgStatus)) {
			lineColor = "darkred";
		}

		var label = document.getElementById("msgHeaderLabel");
        if (label) {
            label.innerHTML = labelHTML;
        }

        var addr = document.getElementById("msgHeaderPhone");
        if (addr) {
			addr.innerHTML = msg.msgAddress;
		}

        var dateTime = document.getElementById("msgHeaderDate")
		if (dateTime) {
            
            var year = msg.msgDate.substr(0, 2);
            var month = msg.msgDate.substr(3, 2);
            var day = msg.msgDate.substr(6, 2);
            var time = msg.msgDate.substr(9, 5);
            
            dateTime.innerHTML = day + "-" + month + "-" + year + " " + time;
		}
        
        var status = document.getElementById("msgHeaderStatus")
		if (status) {
			status.innerHTML = "<span style='color: " + lineColor + ";'>" +  gStatusCode[msg.msgStatus] + "</span>";
		}

        var canvas = document.getElementById("msgContent");
        if (canvas) {
            canvas.innerHTML = msg.msgText;
        }
    }
};

BWWidget.prototype.resetSendButton = function () {
    
    var newButton = document.getElementById("newMessage");
    if (newButton) {    
        newButton.innerHTML = "New";
    }
}

BWWidget.prototype.setupSend = function () {
    
    var newButton = document.getElementById("newMessage");
    if (newButton) {
        
        if (newButton.innerHTML == "Reply") {
            if (this.currentMsgID != null) {
                this.replyToMessage(this.currentMsgID);
            }
        }
    }
    var field = document.getElementById("DestinationInputField");
    if (field) {
        field.focus();
    }
}

BWWidget.prototype.replyToMessage = function(msgIdx) {

    if (this.activeMailbox == "in") {
        
        var address = document.getElementById("DestinationInputField");
        if (address) {
    
            var mailbox = this.inbox;
            var msg = mailbox[msgIdx];
     
            if (msg) {
                address.value = msg.msgAddress;
            }
            address.focus();
        }
    }
};


BWWidget.prototype.trimStr = function (str) {

    var newStr = str.replace(/\s/g, '');
    return newStr.replace(/[+]/g, '');
}

BWWidget.prototype.parseMessageFeed = function (xml) {

    gDebug.log("Parsing RSS message feed");

    var findChild = function (element, nodeName) {

        var childNode = null;
        for (childNode = element.firstChild; childNode != null; childNode = childNode.nextSibling) {
            if (childNode.nodeName == nodeName)
                return childNode;
        }
        return null;
    }

    var formatDate = function (xmlDate) {

        var date = xmlDate.substring(2, 10);
        date += " " + xmlDate.substring(11, 16);

        return date;
    }

/*
    var dumpObj = function (obj) {

        gDebug.log('Dumping object');
        for (var prop in obj) {
            gDebug.log(prop);
            gDebug.log(obj[prop]);
        }
    }
*/

    // Get the top level <rss> element
    var rss = findChild(xml, 'rss');
    if (!rss) {
        gDebug.log("no <rss> element");
        return;
    }

    // Get single subordinate channel element
    var channel = findChild(rss, 'channel');
    if (!channel) {
        gDebug.log("no <channel> element");
        return;
    }

    if (this.activeMailbox == "out") {
        this.sentbox = [];
    }
    else {
        this.inbox = [];
    }

    var accountInfo = findChild(channel, "account:account");
    if (accountInfo) {

        var accNode = findChild(accountInfo, "account:balance");
        if (accNode) {
            this.accountBalance = accNode.firstChild.nodeValue;
            gDebug.log("Account balance: " + this.accountBalance);
        }
        accNode = findChild(accountInfo, "account:accountType");
        if (accNode) {
            this.accountType = accNode.firstChild.nodeValue;
            gDebug.log("Account type: " + this.accountType);            
        }
        accNode = findChild(accountInfo, "account:currencyType");
        if (accNode) {
            this.currencyStr = accNode.firstChild.nodeValue;
            gDebug.log("Account currency: " + this.currencyStr);
        }
    }
    else {
        gDebug.log("Account info element not found");
    }

    var itemList = xml.getElementsByTagName("item");
    for (var idx = 0; idx < itemList.length; idx++)
    {
        var item = itemList.item(idx);
        if (item.nodeName == 'item') {

            var guid = findChild(item, 'guid');
            var msgNode = findChild(item, 'message:message');
            if (msgNode != null) {
                
                var msg = new Message();

                msg.msgURL = guid.firstChild.nodeValue;
                var node = findChild(msgNode, 'message:statusDate');
                if (node) {
                    msg.msgDate = formatDate(node.firstChild.nodeValue);
                }

                node = findChild(msgNode, 'message:body');
                if (node) {
                    msg.msgText = node.firstChild.nodeValue;
                }
                node = findChild(msgNode, 'message:statusCode');
                if (node) {
                    msg.msgStatus = node.firstChild.nodeValue;
                }

                var recipientNode = findChild(msgNode, 'message:recipient');
                if (recipientNode) {

                    node = findChild(recipientNode, 'message:displayname');
                    if (node) {
                        msg.msgAddress = node.firstChild.nodeValue;
                    }
                }

                // dumpObj(msg);
                gDebug.log("Adding msg obj to mailbox " + this.activeMailBox);
                if (this.activeMailbox == "out") {
                    this.sentbox.push(msg);
                }
                else {
                    this.inbox.push(msg);
                }
            }
        }
    }
    this.showMailBox(this.activeMailbox);
};


