<repo_name>GamingMaster2000/BPUsageMeter<file_sep>/js/methods/gm2k300.js
// JavaScript Document
function gm2k300(){
	this.uid = 'gm2k300';
	this.name = 'GM2K 3.0.0';
	this.priority = 10;
	this.enabled = true;
	
	this.accountId = '';
	this.serviceId = '';
	
	this.Run =	function()
				{
					UsageGadget.logger.LogMessage("INFO", "Running method: " + this.name);

					var that = this;
					var servicesPage = new WebLoading(UsageGadget.logger);
					servicesPage.onsuccess = function(responseText){that.ServicesPageLoaded(responseText);};
					servicesPage.onfail = function(){that.FailedPageLoading();};
					servicesPage.url = 'https://www.my.telstra.com.au/myaccount/overview';
					servicesPage.LoadPage();
				}
				
	this.FailedPageLoading =	function()
								{
									UsageGadget.logger.LogMessage("WARNING", "Failed to load the webpage.");
									UsageGadget.CheckNextMethod();
								}
	
	this.ServicesPageLoaded =	function(responseText)
								{
									try{
										var overviewPage = document.createElement('div');
										overviewPage.innerHTML = responseText;
										var internetRows = overviewPage.getElementsByTagName("a");
										var urlOfUsage = 'internet-daily-usage.json';
										for(var i = 0; i < internetRows.length; i++){
											try{
												if(internetRows[i].getElementsByTagName('i').length < 1)
													continue;

												if(internetRows[i].getElementsByTagName('i')[0].innerHTML == UsageGadget.username){
													var url = internetRows[i].href;
													
													var regex = new RegExp("accountId=([a-zA-Z0-9]+).*?serviceId=([a-zA-Z0-9]+)", "g");
													var details = regex.exec(url);
													
													this.accountId = details[1];
													this.serviceId = details[2];
													break;
												}
											}catch(err){
											}
										}
										
										//Throw an error if details not found.
										//Sometimes caused it to get stuck on 'REFRESHING'
										if(this.accountId == '' || this.serviceId == ''){
											UsageGadget.logger.LogMessage("ERROR", "Couldn't find accountId or serviceId.");
											UsageGadget.CheckNextMethod();
											return;									
										}
										
										var that = this;
										var detailsPage = new WebLoading(UsageGadget.logger);
										detailsPage.onsuccess = function(responseText){that.DetailsLoaded(responseText);};
										detailsPage.onfail = function(){that.FailedPageLoading();};
										detailsPage.url = 'https://www.my.telstra.com.au/myaccount/internet-daily-usage.json?accountId=' + this.accountId + '&serviceId=' + this.serviceId;
										detailsPage.LoadPage();
									}catch(err){
										UsageGadget.logger.LogMessage("ERROR", "Couldn't find accountId or serviceId.");
										UsageGadget.CheckNextMethod();
										return;
									}
								}
								
	this.DetailsLoaded =	function(responseText)
							{
								UsageGadget.logger.LogMessage("INFO", "Getting usage info and passing it to the gadget to display!");
								try{
									var usageInfo = JSON.parse(responseText);
									var data = new DataToDisplay();
									var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
									
									data.totalUsage = usageInfo.result.totalUsage;
									data.allowance = usageInfo.result.allowanceUsage;
									
									//Sometimes the start/end dates are wrong (Turns out it's to do with timezones)
									//Try a messy (but more accurate) way first but
									//fall back to Telstra provided values if necessary
									try{
										var Period = /^\(([0-9]+ [a-z]+) - ([0-9]+ [a-z]+)\)$/i.exec(usageInfo.result.headerDateRange);
										var startParts = /([0-9]+) ([a-z]+)/i.exec(Period[1]);
										var endParts = /([0-9]+) ([a-z]+)/i.exec(Period[2]);

										if(monthNames[(new Date()).getMonth()] == 'Jan' && startParts[2] == 'Dec'){
											startParts.push((new Date()).getFullYear() - 1);
										}else{
											startParts.push((new Date()).getFullYear());
										}
			
										if(monthNames[(new Date()).getMonth()] == 'Dec' && endParts[2] == 'Jan'){
											endParts.push((new Date()).getFullYear() + 1);	
										}else{
											endParts.push((new Date()).getFullYear());
										}

										data.startDate = (new Date(startParts[1] + " " + startParts[2] + " " + startParts[3])).getTime();
										data.endDate = (new Date(endParts[1] + " " + endParts[2] + " " + endParts[3])).getTime();	
									}catch(err){
										data.startDate = usageInfo.result.startDate;
										data.endDate = usageInfo.result.endDate;
									}
																											
									//Try to avoid some Telstra issues.
									if(data.allowance > 0){
										System.Gadget.Settings.write("lastGoodAllowance", data.allowance);
										System.Gadget.Settings.write("lastGoodStart", data.startDate);
										System.Gadget.Settings.write("lastGoodEnd", data.endDate);
									}else{
										data.allowance = System.Gadget.Settings.read("lastGoodAllowance");
										data.startDate = System.Gadget.Settings.read("lastGoodStart");
										data.endDate = System.Gadget.Settings.read("lastGoodEnd");
									}
																	
									var unratedUsage = 0;
									try{
										for(var i = 0; i < usageInfo.result.usageList.length; i++){
											unratedUsage += usageInfo.result.usageList[i].unratedUsage;
										}
									}catch(err){
										UsageGadget.logger.LogMessage("ERROR", "Couldn't get 'Unrated Usage'. Error: " + err.message);
									}
									
									data.unratedUsage = unratedUsage;
									
									data.flyoutData = this.BuildFlyoutPage(usageInfo, data);
									data.raw = responseText;
									
									UsageGadget.DisplayData(data);
								}catch(err){
									UsageGadget.logget.LogMessage("ERROR", "Error getting the usage data. Message: " + err.message);	
								}
							}
	
	this.BuildFlyoutPage = 	function (usageInfo, data)
							{
								var usageGb = usageInfo.result.totalUsage / 1000;
								var unratedGb = data.unratedUsage / 1000;
								var allowanceGb = usageInfo.result.allowanceUsage / 1000;
								
								var maxYLabel = (usageInfo.result.maxYAxis > 1000 ? usageInfo.result.maxYAxis / 1000 + 'GB' : usageInfo.result.maxYAxis + 'MB');
								var halfYLabel = (usageInfo.result.maxYAxis / 2 > 1000 ? usageInfo.result.maxYAxis / 2 / 1000 + 'GB' : usageInfo.result.maxYAxis / 2 + 'MB');		
								
								var output = '	<div style="margin-bottom: 10px;">\
													<h5>PLAN DETAILS</h5>\
													<table width="100%" class="font" style="margin-top: 5px;">\
														<tr>\
															<td width="25%" style="font-weight: bold;">Current Account Usage</td>\
															<td>' + usageGb + 'GB (+ ' + unratedGb + 'GB Unrated Usage)</td>\
														</tr>\
														<tr>\
															<td style="font-weight:bold">Current Usage Allowance</td>\
															<td>' + allowanceGb + 'GB</td>\
														</tr>\
														<tr>\
															<td style="font-weight:bold">Account Usage Status</td>\
															<td>' + (usageInfo.result.speedSlowed ? 'Slowed' : 'In Allowance') + '</td>\
														</tr>\
														<tr>\
															<td style="font-weight:bold">Current Bill Period</td>\
															<td>' + usageInfo.result.headerDateRange.substring(1, usageInfo.result.headerDateRange.length - 1) + '</td>\
														</tr>\
													</table>\
												</div>';

								output += '		<div style="margin-top:10px;">\
													<table class="breakdown_table">\
														<thead>\
															<tr>\
																<td>Date</td>\
																<td>Download (MB)</td>\
																<td>Upload (MB)</td>\
																<td>Total (MB)</td>\
																<td>Unmetered (MB)</td>\
																<td>Unrated (MB)</td>\
															</tr>\
														</thead>\
														<tbody>';
								
								var row = 0;
								
								for(var i = 0; i < usageInfo.result.usageList.length; i++){
									output += '				<tr class="row' + (row++ % 2) + '">\
																<td>' + usageInfo.result.usageList[i].usageDisplayDate + '</td>\
																<td>' + usageInfo.result.usageList[i].downloadUsage + '</td>\
																<td>' + usageInfo.result.usageList[i].uploadUsage + '</td>\
																<td>' + usageInfo.result.usageList[i].totalUsage + '</td>\
																<td>' + usageInfo.result.usageList[i].freeUsage + '</td>\
																<td>' + usageInfo.result.usageList[i].unratedUsage + '</td>\
															</tr>';	
								}
								
								output += '				</tbody>\
														<tfoot style="font-weight: bold;">\
															<tr>\
																<td>Total</td>\
																<td>' + usageInfo.result.downloadUsage + '</td>\
																<td>' + usageInfo.result.uploadUsage + '</td>\
																<td>' + usageInfo.result.totalUsage + '</td>\
																<td>' + usageInfo.result.freeUsage + '</td>\
																<td>' + data.unratedUsage + '</td>\
															</tr>\
														</tfoot>\
													</table>\
												</div>';

								return output;	
							}
}<file_sep>/js/Logger.js
// JavaScript Document
function Logger() 
{
	this.opened = false;
	this.logger = null;
	this.user = '';
	
	//Open Log File
	this.Open = 		function(){
							if(this.opened){
								//Log opened. Close the current log before continuing.
								this.Close();
							}

							//Open a log file
							try{
								var fso = new ActiveXObject("Scripting.FileSystemObject");
								try{
									this.logger = fso.OpenTextFile(System.Gadget.path + "\\logs\\log_" + this.user + ".txt", 8, true, 0);
									this.opened = true;
								}catch(err){
									this.opened = false;
								}
							}catch(err){
								this.opened = false;
							}
						}
	
	//Close Log File
	this.Close = 		function(){
							if(this.opened){
								this.logger.Close();
								this.opened = false;
							}
						}
	
	//Log a Message
	this.LogMessage = 	function(prefix, message){
							if(this.opened){
								var currentdate = new Date(); 
								var datetime = currentdate.getDate() + "/"
											+ (currentdate.getMonth()+1)  + "/" 
											+ currentdate.getFullYear() + " "  
											+ (currentdate.getHours() < 10 ? "0" : "") + currentdate.getHours() + ":"  
											+ (currentdate.getMinutes() < 10 ? "0" : "") + currentdate.getMinutes() + ":" 
											+ (currentdate.getSeconds() < 10 ? "0" : "") + currentdate.getSeconds();
											
								this.logger.WriteLine("[" + datetime + " " + prefix + "] " + message);
							}
						}
}<file_sep>/README.md
# BPUsageMeter
Bigpond Usage Meter Windows Gadget

Windows Gadget to monitor Bigpond Usage.

"Pre-compiled" versions are currently found at http://www.gm2k.net/gadgets/bpusagemeter/

To install these repository files for a "bleeding edge build" you can either:

Copy them to the folder your gadget is currently installed in (usually %LocalAppData%\Microsoft\Windows Sidebar\Gadgets\BPUsageMeter.gadget)

OR

You can download these files, Place them in a zip file and rename that file so the extension is .gadget. This will allow you to install the gadget like you would any other.<file_sep>/js/styles/Classic.js
// JavaScript Document
function Classic(){
	this.uid = 'style_classic';
	this.timeTransition = 2;
	this.Name = 'Classic';
	this.priority = 10;
	this.flyoutData = null;
	
	this.initialise = 	function(firstRun){
							if(firstRun){
								var dockedCSS=document.createElement("link");
								dockedCSS.setAttribute("rel", "stylesheet");
								dockedCSS.setAttribute("type", "text/css");
								dockedCSS.setAttribute("href", "css/style_docked.css");
								dockedCSS.setAttribute("id", "styleDocked");
								dockedCSS.setAttribute("title", "docked");
								
								var undockedCSS=document.createElement("link");
								undockedCSS.setAttribute("rel", "stylesheet");
								undockedCSS.setAttribute("type", "text/css");
								undockedCSS.setAttribute("href", "css/style_undocked.css");
								undockedCSS.setAttribute("id", "styleUndocked");
								undockedCSS.setAttribute("title", "undocked");
								undockedCSS.setAttribute("disabled", true);
								
								document.getElementsByTagName("head")[0].appendChild(dockedCSS);
								document.getElementsByTagName("head")[0].appendChild(undockedCSS);
							}

							var that = this;
							System.Gadget.Flyout.file = "classic_flyout.html";
							System.Gadget.onUndock = function(){that.CheckDockState()};
							System.Gadget.onDock = function(){that.CheckDockState()};

							document.body.innerHTML = '	<div id="mainheader">BIGPOND USAGE</div>\
														<div id="container">\
															<span id="usageOverlay">\
																<div id="usageBlock">\
																	<div id="barEmpty1">\
																		<div id="bar1" class="barFill"><img src="img/1x1pix_trans.gif" width="1" height="1"></div>\
																	</div>\
																	<div id="usageheader">\
																		<div style="float:left">USAGE</div>\
																		<div style="float:right" id="percentUsed">0%</div>\
																	</div>\
																	<div class="font">\
																		<div id="usage" style="float:right;">0 / 0GB</div>\
																	</div>\
																</div>\
															</span>\
															<span id="monthOverlay">\
																<div id="monthBlock">\
																	<div id="barEmpty2">\
																		<div id="bar2" class="barFill"><img src="img/1x1pix_trans.gif" width="1" height="1"></div>\
																	</div>\
																	<div id="monthheader">\
																		<div style="float:left">MONTH</div>\
																		<div style="float:right" id="percentMonth">0%</div>\
																	</div>\
																	<div class="font">\
																		<div id="monthRemaining" style="float:right;">0 DAYS</div>\
																	</div>\
																</div>\
															</span>\
															<div id="controlBlock">\
																<div class="icon icon-paper" onMouseOver="UsageGadget.style.SetIconColour(\'details\', \'over\')" onMouseOut="UsageGadget.style.SetIconColour(\'details\', \'normal\')" onClick="UsageGadget.style.OpenFlyout();">\
																	<div id="icon-details" class="icon-details"><img src="img/1x1pix_trans.gif" width="9" height="9"></div>\
																	<div id="icon-details-box" class="icon-details-box"><img src="img/1x1pix_trans.gif" width="1" height="1"></div>\
																</div>\
																<div class="icon icon-down" onMouseOver="UsageGadget.style.SetIconColour(\'refresh\', \'over\')" onMouseOut="UsageGadget.style.SetIconColour(\'refresh\', \'normal\')" onClick="UsageGadget.retrieveData();">\
																	<div id="icon-refresh" class="icon-refresh"><img src="img/1x1pix_trans.gif" width="9" height="9"></div>\
																	<div id="icon-refresh-triangle" class="icon-refresh-triangle"><img src="img/1x1pix_trans.gif" width="1" height="1"></div>\
																	<div id="icon-refresh-line" class="icon-refresh-line"><img src="img/1x1pix_trans.gif" width="1" height="1"></div>\
																</div>\
																<div id="lastUpdated" class="font10"" style="float:right;"></div>\
															</div>\
														</div>\
														<div class="font10" id="accountName">' + (System.Gadget.Settings.read('displayAccount') ? System.Gadget.Settings.read('bigpondUsername') : '') + '</div>';

							if (System.Gadget.docked)
								this.setTheme("docked");
							else
								this.setTheme("undocked");

							this.SetColours();
							this.CheckDockState();
						}
		
		this.SetColours = 	function()
							{
								var bgColor = System.Gadget.Settings.read("bgcolor");
								var borderColor = System.Gadget.Settings.read("bordercolor");
								var textColor = System.Gadget.Settings.read("textcolor");
								var barTextColor = System.Gadget.Settings.read("bartextcolor");
								var bar1color = System.Gadget.Settings.read("bar1color");
								var bar2color = System.Gadget.Settings.read("bar2color");
								var baremptycolor = System.Gadget.Settings.read("baremptycolor");
								var iconcolorload = System.Gadget.Settings.read("iconcolor");
								var hideDividers = System.Gadget.Settings.read("hideDividers");

								document.body.style.backgroundColor = bgColor;
								document.body.style.borderColor = borderColor;
								document.getElementById("usageBlock").style.borderTopColor = (hideDividers) ? bgColor : borderColor;
								document.getElementById("monthBlock").style.borderTopColor = (hideDividers) ? bgColor : borderColor;
								document.getElementById("controlBlock").style.borderTopColor = (hideDividers) ? bgColor : borderColor;
							
								document.getElementById("bar1").style.backgroundColor = bar1color;
								document.getElementById("bar2").style.backgroundColor = bar2color;
								document.getElementById("barEmpty1").style.backgroundColor = baremptycolor;
								document.getElementById("barEmpty2").style.backgroundColor = baremptycolor;
								
								document.getElementById("mainheader").style.color = textColor;
								document.getElementById("usage").style.color = textColor;
								document.getElementById("monthremaining").style.color = textColor;
								document.getElementById("lastupdated").style.color = textColor;
								document.getElementById("usageheader").style.color = barTextColor;
								document.getElementById("monthheader").style.color = barTextColor;
								document.getElementById("accountName").style.color = textColor;
								
								iconcolour = iconcolorload ? iconcolorload : "#000000";
								iconcolourover = bar1color ? bar1color : "#FF6600";
								
								this.SetIconColour("details", "normal");
								this.SetIconColour("refresh", "normal");
							}
						
		this.CheckDockState = 	function() 
								{		
									System.Gadget.beginTransition();
									
									if (System.Gadget.docked)
									{		
										this.setTheme("docked");
										
										var useHeight = 120;
										if(System.Gadget.Settings.read("displayAccount")){
											useHeight = 131;
										}
										
										with (document.body.style) {
											width = 130;
											height = useHeight;
										}
									}
									else
									{
										this.setTheme("undocked");
										
										var useHeight = 185;
										if(System.Gadget.Settings.read("displayAccount")){
											useHeight = 201;
										}
								
										with (document.body.style) {
											width = 200;
											height = useHeight;
										}
									}
									System.Gadget.endTransition(System.Gadget.TransitionType.morph, this.timeTransition);
								}
		
		this.SetStatus = 	function(status)
							{
								document.getElementById("lastUpdated").innerHTML = status;
						 	}
							
		this.GetStatus = 	function()
							{
								return document.getElementById("lastUpdated").innerHTML;
							}
							
		this.setTheme = function(theme)
						{
							var styleUndocked = document.getElementById("styleUndocked");
							var styleDocked = document.getElementById("styleDocked");

							switch(theme)
							{
								case "docked":
									styleUndocked.disabled = true;
									styleDocked.disabled = false;
									break;
								
								case "undocked":
									styleUndocked.disabled = false;
									styleDocked.disabled = true;
									break;
							}	
						}
		
		this.LoadSettings = function(settingsContainer)
							{
								var scriptNode = document.createElement('script');
								scriptNode.setAttribute('src', "jscolor/jscolor.js");
								scriptNode.setAttribute('type', "text/javascript");
								document.getElementsByTagName('head')[0].appendChild(scriptNode);
								
								var bar1color = System.Gadget.Settings.read("bar1color") ? System.Gadget.Settings.read("bar1color") : "#FF6600";
								var bar2color = System.Gadget.Settings.read("bar2color") ? System.Gadget.Settings.read("bar2color") : "#3399CC";
								var baremptycolor = System.Gadget.Settings.read("baremptycolor") ? System.Gadget.Settings.read("baremptycolor") : "#CCCCCC";
								var bgcolor = System.Gadget.Settings.read("bgcolor") ? System.Gadget.Settings.read("bgcolor") : "#FFFFFF";
							
								var bordercolor = System.Gadget.Settings.read("bordercolor") ? System.Gadget.Settings.read("bordercolor") : "#000000";
								var textcolor = System.Gadget.Settings.read("textcolor") ? System.Gadget.Settings.read("textcolor") : "#000000";
								var bartextcolor = System.Gadget.Settings.read("bartextcolor") ? System.Gadget.Settings.read("bartextcolor") : "#FFFFFF";
								var iconcolor = System.Gadget.Settings.read("iconcolor") ? System.Gadget.Settings.read("iconcolor") : "#000000";
								
								var dividerDiv = document.createElement('div');
								dividerDiv.className = 'row';
								dividerDiv.innerHTML = '<div class="label"><strong>Hide Dividers:</strong></div>\
														<div class="field">Yes <input type="radio" name="hideDividers" value="1" ' + (System.Gadget.Settings.read("hideDividers") ? 'CHECKED' : '') + '> \
																		No<input type="radio" name="hideDividers" value="0" ' + (!System.Gadget.Settings.read("hideDividers") ? 'CHECKED' : '') + '></div>';
								settingsContainer.appendChild(dividerDiv);
								
								var mouseOverDiv = document.createElement('div');
								mouseOverDiv.className = 'row';
								mouseOverDiv.innerHTML = '	<div class="row">\
																<div class="label"><strong>Mouseover Details:</strong></div>\
																<div class="field">\
																	Yes <input type="radio" name="mouseoverDetails" value="1" ' + (System.Gadget.Settings.read("mouseoverDetails") ? 'CHECKED' : '') + '> \
																	No<input type="radio" name="mouseoverDetails" value="0" ' + (!System.Gadget.Settings.read("mouseoverDetails") ? 'CHECKED' : '') + '>\
																</div>\
															</div>';
								
								settingsContainer.appendChild(mouseOverDiv);
								
								var mixedUnitsDiv = document.createElement('div');
								mixedUnitsDiv.className = 'row';
								mixedUnitsDiv.innerHTML = '	<div class="row">\
																<div class="label"><strong>Use Mixed Units:</strong></div>\
																<div class="field">\
																	Yes <input type="radio" name="mixedUnits" value="1" ' + (System.Gadget.Settings.read("mixedUnits") ? 'CHECKED' : '') + '> \
																	No<input type="radio" name="mixedUnits" value="0" ' + (!System.Gadget.Settings.read("mixedUnits") ? 'CHECKED' : '') + '>\
																</div>\
															</div>';
								
								settingsContainer.appendChild(mixedUnitsDiv);

								var blankRow = document.createElement('div');
								blankRow.className = 'row';
								blankRow.innerHTML = '<br /><hr style="border:none; border-top:1px dotted black; height:1px;">';
								settingsContainer.appendChild(blankRow);
								
								var resetColours = document.createElement('strong');
								resetColours.innerHTML = 'Colours:&nbsp;&nbsp;';
								settingsContainer.appendChild(resetColours);
								
								var resetLink = document.createElement('a');
								resetLink.innerHTML = "Reset";
								resetLink.href = '#';
								var that = this;
								resetLink.onclick = function(){that.resetColours(); return false;};
								settingsContainer.appendChild(resetLink);
								
								var colourTable = document.createElement('div');
								colourTable.innerHTML = '<table width=100% cellpadding=1 callspacing=0 border=0>\
															<tr class="font">\
																<td>Bar 1</td>\
																<td>Bar 2</td>\
																<td>Bar Empty</td>\
																<td>Background</td>\
															</tr>\
															<tr>\
																<td><input class="color {hash:true}" id="bar1color" value="' + bar1color + '" size="6"></td>\
																<td><input class="color {hash:true}" id="bar2color" value="' + bar2color + '" size="6"></td>\
																<td><input class="color {hash:true}" id="baremptycolor" value="' + baremptycolor + '" size="6"></td>\
																<td><input class="color {hash:true}" id="bgcolor" value="' + bgcolor + '" size="6"></td>\
															</tr>\
															<tr class="font">\
																<td>Border</td>\
																<td>Text</td>\
																<td>Bar Text</td>\
																<td>Icons</td>\
															</tr>\
															<tr>\
																<td><input class="color {hash:true}" id="bordercolor" value="' + bordercolor + '" size="6"></td>\
																<td><input class="color {hash:true}" id="textcolor" value="' + textcolor + '" size="6"></td>\
																<td><input class="color {hash:true}" id="bartextcolor" value="' + bartextcolor + '" size="6"></td>\
																<td><input class="color {hash:true}" id="iconcolor" value="' + iconcolor + '" size="6"></td>\
															</tr>\
														</table>';
								settingsContainer.appendChild(colourTable);
							}
							
		this.ValidateSettings = function(event)
								{
									
								}
								
		this.SaveSettings = function(event)
							{
								System.Gadget.Settings.write("hideDividers", Radio_Value_Get(document.getElementById('hideDividers')));
								System.Gadget.Settings.write("mouseoverDetails", Radio_Value_Get(document.getElementById('mouseoverDetails')));
								System.Gadget.Settings.write("mixedUnits", Radio_Value_Get(document.getElementById('mixedUnits')));

								System.Gadget.Settings.write("bar1color", bar1color.value);
								System.Gadget.Settings.write("bar2color", bar2color.value);
								System.Gadget.Settings.write("baremptycolor", baremptycolor.value);
								System.Gadget.Settings.write("bgcolor", bgcolor.value);
							
								System.Gadget.Settings.write("bordercolor", bordercolor.value);
								System.Gadget.Settings.write("textcolor", textcolor.value);
								System.Gadget.Settings.write("bartextcolor", bartextcolor.value);
								System.Gadget.Settings.write("iconcolor", iconcolor.value);
							}

		this.resetColours =	function()
							{
								document.getElementById("bar1color").value = "#FF6600";
								document.getElementById("bar1color").style.backgroundColor = "#FF6600";
								document.getElementById("bar1color").style.color = "#FFFFFF";
								document.getElementById("bar2color").value = "#3399CC";
								document.getElementById("bar2color").style.backgroundColor = "#3399CC";
								document.getElementById("bar2color").style.color = "#000000";
								document.getElementById("baremptycolor").value = "#CCCCCC";
								document.getElementById("baremptycolor").style.backgroundColor = "#CCCCCC";
								document.getElementById("baremptycolor").style.color = "#000000";
								document.getElementById("bgcolor").value = "#FFFFFF";
								document.getElementById("bgcolor").style.backgroundColor = "#FFFFFF";
								document.getElementById("bgcolor").style.color = "#000000";
							
								document.getElementById("bordercolor").value = "#000000";
								document.getElementById("bordercolor").style.backgroundColor = "#000000";
								document.getElementById("bordercolor").style.color = "#FFFFFF";
								document.getElementById("textcolor").value = "#000000";
								document.getElementById("textcolor").style.backgroundColor = "#000000";
								document.getElementById("textcolor").style.color = "#FFFFFF";
								document.getElementById("bartextcolor").value = "#FFFFFF";
								document.getElementById("bartextcolor").style.backgroundColor = "#FFFFFF";
								document.getElementById("bartextcolor").style.color = "#000000";
								document.getElementById("iconcolor").value = "#000000";
								document.getElementById("iconcolor").style.backgroundColor = "#000000";
								document.getElementById("iconcolor").style.color = "#FFFFFF";
							}
	
	this.FormatUsage = 	function(info, targetUnits){
							var unitSuffix = ['', 'MB', 'GB', 'TB', 'PB', 'EB', 'YB'];
							
							for(var i = 0; i < unitSuffix.length; i++){
								if(info[1] == unitSuffix[i]){
									info[1] = i;
								}
								
								if(targetUnits && targetUnits == unitSuffix[i]){
									targetUnits = i;	
								}
							}
							
							while((targetUnits && info[1] != targetUnits) || (!targetUnits && info[0] >= 1000)){
								info[0] /= 1000;
								info[1]++;	
							}
							
							info[1] = unitSuffix[info[1]];
						}
	
	this.DisplayData = 	function(data)
						{
							try{
								var usageAccuracy = System.Gadget.Settings.read("usageAccuracy");
								var remainingAccuracy = System.Gadget.Settings.read("remainingAccuracy");
								
								var usageDisplay = [(System.Gadget.Settings.read("usageDisplay") ? data.allowance - data.totalUsage : data.totalUsage), "MB"];
								var quotaDisplay = [data.allowance, "MB"]; //In MB
								
								if(System.Gadget.Settings.read("mixedUnits")){
									//Mix Units
									this.FormatUsage(usageDisplay);
									this.FormatUsage(quotaDisplay);
								}else{	//Don't mix the units, just make them GB
									this.FormatUsage(usageDisplay, "GB");
									this.FormatUsage(quotaDisplay, "GB");
								}
								
								quotaDisplay[0] = roundNumber(quotaDisplay[0], 3); //At most 3 decimal places.
								
								//Dynamically find max number of decimal places. Not fixed because more decimal places where possible is better
								//Particularly if usage is over 1Tb. 3 decimal places makes it accurate to nearest GB. 
								//If possible want accuracy to nearest MB
								var dPs = 10 - quotaDisplay[0].toString().length + (quotaDisplay[0] - Math.floor(quotaDisplay[0]) > 0 ? 1 : 0) - parseInt(usageDisplay[0]).toString().length;
								usageDisplay[0] = roundNumber(usageDisplay[0], Math.max(0, dPs));
								
								
								if(usageDisplay[1] == quotaDisplay[1])
									usageDisplay[1] = '';
								
								//Usage Bar																					
								document.getElementById("usage").innerHTML = usageDisplay[0] + usageDisplay[1] + " \/ " + quotaDisplay[0] + quotaDisplay[1];
								
								if(System.Gadget.Settings.read("usageDisplay")){
									document.getElementById("bar1").style.width = Math.max((data.allowance - data.totalUsage) / data.allowance * 100, 0) + "%";
									document.getElementById("percentUsed").innerHTML = Math.min(roundNumber((data.allowance - data.totalUsage) / data.allowance * 100, usageAccuracy), 100) + "%";
								}else{
									document.getElementById("bar1").style.width = Math.min(data.totalUsage / data.allowance * 100, 100) + "%";
									document.getElementById("percentUsed").innerHTML = Math.max(roundNumber(data.totalUsage / data.allowance * 100, usageAccuracy), 0) + "%";
								}
																				
								//Month Bar		
								var today = new Date();
								var startDate = new Date(data.startDate);
								startDate.setHours(0);
								startDate.setMinutes(0);
								startDate.setSeconds(0);
								
								var endDate = new Date(data.endDate + 24*60*60*1000);
								endDate.setHours(0);
								endDate.setMinutes(0);
								endDate.setSeconds(0);
															
								var monthRemaining =  (endDate.getTime()-today.getTime())/(1000*60*60*24);
								var monthPassed = (today.getTime()-startDate.getTime())/(1000*60*60*24);
								var daysInMonth = (endDate.getTime()-startDate.getTime())/(1000*60*60*24);
								var daysPassed = daysInMonth - (endDate.getTime()-today.getTime())/(1000*60*60*24);
															
								document.getElementById("monthRemaining").innerHTML = (roundNumber(monthRemaining, remainingAccuracy)) + (monthRemaining == 1 ? " DAY" : " DAYS");
								document.getElementById("bar2").style.width = Math.min(monthPassed / daysInMonth * 100 , 100) + "%";
								document.getElementById("percentMonth").innerHTML = roundNumber(monthPassed / daysInMonth * 100, usageAccuracy) + "%";
								
								//Mouseover details
								var perDayRemaining =  [Math.max(0, (data.allowance -  data.totalUsage) / ((monthRemaining < 1) ? 1 : monthRemaining)), "MB"];
								this.FormatUsage(perDayRemaining);
								perDayRemaining[0] = Math.round(perDayRemaining[0] * 1000) / 1000; //Sets to 3 decimal places (regardless of unit)
								perDayRemaining = perDayRemaining[0] + " " + perDayRemaining[1];
		
								var surplusDeficit = ["0", "MB", "Surplus"];
	
								if ((data.allowance / daysInMonth * daysPassed) >= data.totalUsage)
									surplusDeficit = [(data.allowance / daysInMonth * daysPassed) - data.totalUsage, "MB", "Surplus"];
								else
									surplusDeficit = [data.totalUsage - (data.allowance / daysInMonth * daysPassed), "MB", "Deficit"];
									
								this.FormatUsage(surplusDeficit);
								surplusDeficit[0] = Math.round(surplusDeficit[0] * 1000) / 1000; //Sets to 3 decimal places (regardless of unit)
	
								if(System.Gadget.Settings.read("mouseoverDetails")){
									document.getElementById("mainheader").setAttribute("title", UsageGadget.username);
									document.getElementById("usageOverlay").setAttribute("title", surplusDeficit[2] + ": " + surplusDeficit[0] + " " + surplusDeficit[1]);
									document.getElementById("monthOverlay").setAttribute("title", "Per Day Remaining: " + perDayRemaining);	
								}
								
								this.flyoutData = '	<div style="margin-bottom: 5px;">\
														<h5>USAGE</h5>\
														<table width="100%" class="font" style="margin-top: 5px;">\
															<tr>\
																<td width="25%" style="font-weight: bold;">Per Day Remaining</td>\
																<td>' + perDayRemaining + '</td>\
															</tr>\
															<tr>\
																<td style="font-weight:bold">' + surplusDeficit[2] + '</td>\
																<td>' + surplusDeficit[0] + " " + surplusDeficit[1] + '</td>\
															</tr>\
														</table>\
													</div>';
								this.flyoutData += data.flyoutData;
							}catch(err){
								this.flyoutData = err.message;
							}
						}
	
	this.SetIconColour =	function(iconname, status)
							{
								if (iconname == "details")
								{
									if (status == "over")
									{
										document.getElementById("icon-details").style.borderColor = iconcolourover;
										document.getElementById("icon-details-box").style.backgroundColor = iconcolourover;
									}
									else
									{
										document.getElementById("icon-details").style.borderColor = iconcolour;
										document.getElementById("icon-details-box").style.backgroundColor = iconcolour;
									}
								}
								else if (iconname == "refresh")
								{
									if (status == "over")
									{
										document.getElementById("icon-refresh").style.borderColor = iconcolourover;
										document.getElementById("icon-refresh-triangle").style.borderTopColor = iconcolourover;
										document.getElementById("icon-refresh-line").style.backgroundColor = iconcolourover;
									}
									else
									{
										document.getElementById("icon-refresh").style.borderColor = iconcolour;
										document.getElementById("icon-refresh-triangle").style.borderTopColor = iconcolour;
										document.getElementById("icon-refresh-line").style.backgroundColor = iconcolour;
									}
								}
							}
	
	this.OpenFlyout =	function ()
						{
							if (this.flyoutData)
							{
								System.Gadget.Flyout.show = !System.Gadget.Flyout.show;
								
								System.Gadget.Flyout.document.parentWindow.content = this.flyoutData;
							}
						}
}<file_sep>/js/common.js
// JavaScript Document
function LoadJSFiles(path, arrayToStore){
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	var folder = fso.GetFolder(path);
	var fc = new Enumerator(folder.files);

	for(; !fc.atEnd();fc.moveNext()){
		try{
			var fileref = document.createElement('script')
			fileref.setAttribute("type","text/javascript")
			fileref.setAttribute("src", fc.item())
				
			document.getElementsByTagName("head")[0].appendChild(fileref)
							
			var classname = fc.item() + "";
			classname = classname.toString().replace(path + "\\", "").replace(".js", "");
			
			arrayToStore.push(new window[classname]());
		}catch(err){	
		}
	}	
	
	//If priority isn't defined it'll fail gracefully
	try{
		arrayToStore.sort(function(a, b){return a.priority-b.priority});
	}catch(err){	

	}
}

function Radio_Value_Get(radioObj) 
{
	if(!radioObj)
		return "";

	var radioLength = radioObj.length;
	if(radioLength == undefined)
		if(radioObj.checked)
			return radioObj.value;
		else
			return "";
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}

function roundNumber(num, dec) {
	var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
	return result;
}<file_sep>/js/settings/General.js
// JavaScript Document
function General(){
	this.id = 'general';
	this.name = 'General';	
	this.priority = 10; //Lower number == Higher priority
	
	this.usernameField = null;
	this.passwordField = null;
	this.refreshIntervalField = null;
	this.overrideQuotaField = null;
		
	this.Initialise = 	function ()
						{
							this.usernameField = document.createElement('input');
							this.usernameField.type = 'text';
							this.usernameField.id = "bigpondUsername";
							this.usernameField.title = "Username";
							this.usernameField.size = 20;
							this.usernameField.value = System.Gadget.Settings.read("bigpondUsername");
							
							this.passwordField = document.createElement('input');
							this.passwordField.type = '<PASSWORD>';
							this.passwordField.id = '<PASSWORD>';
							this.passwordField.title = 'Password';
							this.passwordField.size = 20;
							this.passwordField.value = System.Gadget.Settings.read("<PASSWORD>");
							
							this.refreshIntervalField = document.createElement('input');
							this.refreshIntervalField.type = 'text';
							this.refreshIntervalField.id = 'refreshInterval';
							this.refreshIntervalField.title = 'Refresh Interval';
							this.refreshIntervalField.size = 20;
							this.refreshIntervalField.value = (System.Gadget.Settings.read("refreshInterval") ? System.Gadget.Settings.read("refreshInterval") : 60);
							
							this.overrideQuotaField = document.createElement('input');
							this.overrideQuotaField.type = 'text';
							this.overrideQuotaField.id = 'overrideQuota';
							this.overrideQuotaField.title = 'Override Quota';
							this.overrideQuotaField.size = 20;
							this.overrideQuotaField.value = System.Gadget.Settings.read("overrideQuota");
						}
	
	this.CreateRow = 	function(label, input)
						{
							var rowDiv = document.createElement('div');
							rowDiv.className = 'row';
							
							var labelDiv = document.createElement('div');
							labelDiv.className = 'label';
							labelDiv.innerHTML = "<strong>" + label + ":</strong>";
							
							var fieldDiv = document.createElement('div');
							fieldDiv.className = 'field';
							fieldDiv.appendChild(input);
							
							rowDiv.appendChild(labelDiv);
							rowDiv.appendChild(fieldDiv);
							
							return rowDiv;
						}
	
	this.Display = 	function (tabContent)
					{
						var node = document.createElement('div');
						
						node.appendChild(this.CreateRow('Username', this.usernameField));
						node.appendChild(this.CreateRow('Password', this.passwordField));
						node.appendChild(this.CreateRow('Refresh Interval (mins)', this.refreshIntervalField));
						node.appendChild(this.CreateRow('Override Quota (GB)', this.overrideQuotaField));
						
						//I.E. handles radio buttons stupidly so just manually handle them
						var radioButtons = document.createElement('div');
						radioButtons.className = 'row';
						radioButtons.innerHTML = '	<div class="label"><strong>Usage Display:</strong></div>\
													<div class="field">	Used <input type="radio" name="usageDisplay" value="0"' + (!System.Gadget.Settings.read("usageDisplay") ? 'CHECKED' : '') + '> \
																		Remaining <input type="radio" name="usageDisplay" value="1"' + (System.Gadget.Settings.read("usageDisplay") ? 'CHECKED' : '') + '>\
													</div>';
						node.appendChild(radioButtons);	
						
						var unratedButtons = document.createElement('div');
						unratedButtons.className = 'row';
						unratedButtons.innerHTML = '	<div class="label"><strong>Unrated as Metered:</strong></div>\
														<div class="field">	Yes <input type="radio" name="includeUnrated" value="1"' + (System.Gadget.Settings.read("includeUnrated") ? 'CHECKED' : '') + '> \
																			No <input type="radio" name="includeUnrated" value="0"' + (!System.Gadget.Settings.read("includeUnrated") ? 'CHECKED' : '') + '>\
													</div>';
						node.appendChild(unratedButtons);	
											
						tabContent.appendChild(node);
					}
	
	this.ValidateSettings =	function (event)
							{
								//validate fields	
								if (this.usernameField.value == "")
								{
									UsageGadgetSettings.SetStatus('Please enter your username!');
									event.cancel = true;
									return;
								}
								
								if(this.usernameField.value.indexOf("@") < 0){
									UsageGadgetSettings.SetStatus('Please enter your full username. E.g. <EMAIL>');
									event.cancel = true;
									return;
								}
								
								if (this.passwordField.value == "")
								{
									UsageGadgetSettings.SetStatus("Please enter your password!");
									event.cancel = true;
									return;
								}
								
								if (/^-?\d+$/.test(this.refreshIntervalField.value) == false || this.refreshIntervalField.value < 15)
								{
									UsageGadgetSettings.SetStatus("Refresh interval must be a whole number >= 15!");
									event.cancel = true;
									return;
								}
								
								if (this.overrideQuotaField.value)
								{									
									if (/^\d+(\.\d{1,1})?$/.test(this.overrideQuotaField.value) == false || this.overrideQuotaField.value < 1)
									{
										UsageGadgetSettings.SetStatus("Override Quota must be a number >= 1!");
										event.cancel = true;
										return;
									}
								}
							}
	
	this.SaveSettings = function(event)
						{
							System.Gadget.Settings.write("bigpondUsername", this.usernameField.value.toLowerCase());
							System.Gadget.Settings.write("bigpondPassword", <PASSWORD>.<PASSWORD>Field.value);
							System.Gadget.Settings.write("refreshInterval", this.refreshIntervalField.value);
							System.Gadget.Settings.write("overrideQuota", this.overrideQuotaField.value);
							System.Gadget.Settings.write("usageDisplay", Radio_Value_Get(document.getElementsByName('usageDisplay')));
							System.Gadget.Settings.write("includeUnrated", Radio_Value_Get(document.getElementsByName('includeUnrated')));
						}
}<file_sep>/js/settings/Appearance.js
// JavaScript Document
function Appearance(){
	this.id = 'appearance';
	this.name = 'Appearance';	
	this.priority = 20;
	this.styles = [];
	this.style = null;
		
	this.Initialise = 	function ()
						{
							LoadJSFiles(System.Gadget.path + "\\js\\styles", this.styles);
							
							var stylename = System.Gadget.Settings.read("style");
							this.style = this.styles[0]; //Sets a default just in case one can't be found
	
							for(var i = 0; i < this.styles.length; i++){
								if(this.styles[i].uid == stylename){
									this.style = this.styles[i];
									break;	
								}
							}
						}
						
	this.Display = 	function (tabContent)
					{
						var container = document.createElement('div');
						container.innerHTML = '<strong>Select Style:</strong> ';
						
						var selector = document.createElement('select');
						selector.id = 'styleSelect';
						
						container.appendChild(selector);
						container.appendChild(document.createElement('hr'));
						
						for(var i = 0; i < this.styles.length; i++){
							//Add option to the style selector
							var option = document.createElement('option');
							option.value = this.styles[i].uid;
							option.text = this.styles[i].Name;
							
							var styleSettings = document.createElement('div');
							styleSettings.id = 'appearance_' + this.styles[i].uid + '_settings';
							container.appendChild(styleSettings);
														
							if(this.styles[i].uid == this.style.uid){
								option.selected = true;
							}else{
								styleSettings.style.display = "none";
							}
								
							selector.add(option);
							
							//Load any style settings that may be there!
							try{
								this.styles[i].LoadSettings(styleSettings);
							}catch(err){	
							}
						}
						
						var that = this;
						selector.onchange = function(){that.ShowStyleSettings(this)};

						tabContent.appendChild(container);
					}

	this.ShowStyleSettings = 	function(selector)
								{
									var	uid = selector.options[selector.selectedIndex].value;							
									for(var i = 0; i < this.styles.length; i++){
										document.getElementById('appearance_' + this.styles[i].uid + '_settings').style.display = "none";
										
										if(uid == this.styles[i].uid)
											document.getElementById('appearance_' + this.styles[i].uid + '_settings').style.display = '';
									}
								}
								
	this.ValidateSettings = function(event)
							{
								for(var i = 0; i < this.styles.length; i++){
									this.styles[i].ValidateSettings(event);
									if(event.cancel)
										return;	
								}
							}
							
	this.SaveSettings = function(event)
						{
							var selector = document.getElementById('styleSelect');
							System.Gadget.Settings.write("style", selector.options[selector.selectedIndex].value);
							
							for(var i = 0; i < this.styles.length; i++){
								this.styles[i].SaveSettings(event);
							}
						}
}<file_sep>/js/settings/Misc.js
// JavaScript Document
function Misc(){
	this.id = 'misc';
	this.name = 'Misc';
	this.priority = 30;
	
	this.Initialise = 	function ()
						{
						}
	
	this.Display = 	function (tabContent)
					{
						var node = document.createElement('div');

						var useErrorLog = System.Gadget.Settings.read("useErrorLog");
						var displayAccount = System.Gadget.Settings.read("displayAccount");
						var use12hourtime = System.Gadget.Settings.read("use12hourtime");
						var hideFailedMessages = System.Gadget.Settings.read("hideFailedMessages");
						var usageAccuracy = (System.Gadget.Settings.read("usageAccuracy") ? System.Gadget.Settings.read("usageAccuracy") : 0);
						var remainingAccuracy = (System.Gadget.Settings.read("remainingAccuracy") ? System.Gadget.Settings.read("remainingAccuracy") : 1);
						
						node.innerHTML = '	<div class="row">\
												<div class="label">\
													<strong>Log Errors & Debug Messages:</strong>\
												</div>\
												<div class="field">\
													Yes <input type="radio" name="logErrors" value="1" ' + (useErrorLog ? 'CHECKED' : '') + '> \
													No<input type="radio" name="logErrors" value="0" ' + (!useErrorLog ? 'CHECKED' : '') + '>\
												</div>\
											</div>\
											<div class="row">\
												<div class="field">\
													<a href="' + System.Gadget.path + '\\logs\\">Open Log Folder</a>\
												</div>\
											</div>\
											<div class="row">\
												<div class="label">\
													<strong>Display Account Name:</strong>\
												</div>\
												<div class="field">\
													Yes <input type="radio" name="displayAccount" value="1" ' + (displayAccount ? 'CHECKED' : '') + '> \
													No<input type="radio" name="displayAccount" value="0" ' + (!displayAccount ? 'CHECKED' : '') + '>\
												</div>\
											</div>\
											<div class="row">\
												<div class="label">\
													<strong>Use 12 hour time:</strong>\
												</div>\
												<div class="field">\
													Yes <input type="radio" name="use12hourtime" value="1" ' + (use12hourtime ? 'CHECKED' : '') + '> \
													No<input type="radio" name="use12hourtime" value="0" ' + (!use12hourtime ? 'CHECKED' : '') + '>\
												</div>\
											</div>\
											<div class="row">\
												<div class="label">\
													<strong>Only "As of" Label:</strong>\
												</div>\
												<div class="field">\
													Yes <input type="radio" name="hideFailedMessages" value="1" ' + (hideFailedMessages ? 'CHECKED' : '') + '> \
													No<input type="radio" name="hideFailedMessages" value="0" ' + (!hideFailedMessages ? 'CHECKED' : '') + '>\
												</div>\
											</div>\
											<div class="row"><br></div>\
											<div class="row">\
											<strong>Value Accuracy (Decimal Places):</strong><br>\
											<table>\
												<tr class="font">\
													<td>Usage/Month</td>\
													<td>Days Remaining</td>\
												</tr>\
												<tr>\
													<td><input type="text" id="usageAccuracy" size=20 value="' + usageAccuracy + '"></td>\
													<td><input type="text" id="remainingAccuracy" size=20 value="' + remainingAccuracy + '"></td>\
												</tr>\
											</table>\
											</div>';
						
						tabContent.appendChild(node);
					}
	
	this.ValidateSettings = function(event)
							{
								if(document.getElementById('usageAccuracy').value){
									IsFound = /^-?\d+$/.test(document.getElementById('usageAccuracy').value);	
									
									if(IsFound == false || document.getElementById('usageAccuracy').value < 0){
										UsageGadgetSettings.SetStatus("Usage/Month Accuracy must be a number 0 or greater.");
										event.cancel = true;
										return;
									}
								}
								
								if(document.getElementById('remainingAccuracy').value){
									IsFound = /^-?\d+$/.test(document.getElementById('remainingAccuracy').value);	
									
									if(IsFound == false || document.getElementById('remainingAccuracy').value < 0){
										UsageGadgetSettings.SetStatus("Remaining Time Accuracy must be a number 0 or greater.");
										event.cancel = true;
										return;
									}
								}
							}
							
	this.SaveSettings = function(event)
						{
							System.Gadget.Settings.write("useErrorLog", Radio_Value_Get(document.getElementById('logErrors')));
							System.Gadget.Settings.write("displayAccount", Radio_Value_Get(document.getElementById('displayAccount')));
							System.Gadget.Settings.write("use12hourtime", Radio_Value_Get(document.getElementById('use12hourtime')));
							System.Gadget.Settings.write("hideFailedMessages", Radio_Value_Get(document.getElementById('hideFailedMessages')));
							System.Gadget.Settings.write("usageAccuracy", document.getElementById('usageAccuracy').value);
							System.Gadget.Settings.write("remainingAccuracy", document.getElementById('remainingAccuracy').value);
						}
}<file_sep>/js/methods/gm2k201.js
// JavaScript Document
// JavaScript Document
function gm2k201(){
	this.uid = 'gm2k201';
	this.name = 'GM2K 2.0.1';
	this.priority = 20;
	this.enabled = true;
	
	this.accountId = '';
	this.serviceId = '';
	
	this.Run =	function()
				{
					UsageGadget.logger.LogMessage("INFO", "Running method: " + this.name);

					//Older methods require a different login page so we need to login "again"
					UsageGadget.logger.LogMessage("INFO", "This method requires a different login page so we're calling that now.");
					var that = this;
					var loginPage = new WebLoading(UsageGadget.logger);
					loginPage.method = 'POST';
					loginPage.headers.push(new RequestHeader('Content-Type', 'application/x-www-form-urlencoded'));
					loginPage.postdata = "username=" + UsageGadget.username + "&password=" + UsageGadget.password;
					loginPage.onsuccess = function(responseText){that.LoginOK(responseText);};
					loginPage.onfail = function(){that.FailedPageLoading();};
					loginPage.url = 'https://signon.bigpond.com/login';
					loginPage.waitFor200 = false;
					loginPage.LoadPage();		
				}
	
	this.LoginOK = 	function(responseText)
					{
						var loginOK = /Your username\/password combination is incorrect or incomplete/.exec(responseText);
													
						if (loginOK == "Your username/password combination is incorrect or incomplete"){
							//Shouldn't actually get here since the details should be correct before getting here
							UsageGadget.logger.LogMessage("ERROR", "Logging in failed. Username or Password is incorrect.");
							UsageGadget.CheckNextMethod();
							return;
						}
							
						var that = this;
						var servicesPage = new WebLoading(UsageGadget.logger);
						servicesPage.onsuccess = function(responseText){that.ServicesPageLoaded(responseText);};
						servicesPage.onfail = function(){that.FailedPageLoading();};
						servicesPage.url = 'https://myaccount.bigpond.com/MyServices.do';
						servicesPage.LoadPage();
					}
	
	this.FailedPageLoading =	function()
								{
									UsageGadget.logger.LogMessage("WARNING", "Failed to load the webpage.");
									UsageGadget.CheckNextMethod();
								}
	
	this.ServicesPageLoaded =	function(responseText)
								{
									try{
										UsageGadget.logger.LogMessage("INFO", "'My Services' page loaded. Loading usage page. Method: " + this.name);
										
										var doc = document.createElement('div');
										doc.innerHTML = responseText;
										
										var pTags = doc.getElementsByTagName("p");
										var usageURL = '';

										for(var i = 0; i < pTags.length; i++){
											if(pTags[i].innerHTML == 'Username: ' + UsageGadget.username){
												if(/view usage/ig.exec(pTags[i].parentNode.innerHTML)){
													var linkItems = pTags[i].parentNode.getElementsByTagName('a');
													for(var j = 0; j < linkItems.length; j++)
														if(linkItems[j].innerHTML == 'View usage'){
															usageURL = linkItems[j].href.replace("x-gadget://", "");
															break;	
														}
												}
											}
										}

										if(usageURL == ''){
											UsageGadget.logger.LogMessage("ERROR", "Couldn't find usage URL.");
											UsageGadget.CheckNextMethod();
											return;
										}

										usageURL = "https://myaccount.bigpond.com" + usageURL;

										var that = this;
										var detailsPage = new WebLoading(UsageGadget.logger);
										detailsPage.onsuccess = function(responseText){that.DetailsLoaded(responseText);};
										detailsPage.onfail = function(){that.FailedPageLoading();};
										detailsPage.url = usageURL;
										detailsPage.LoadPage();										
									}catch(err){
										UsageGadget.logger.LogMessage("ERROR", "Couldn't find usage URL. Message: " + err.message);
										UsageGadget.CheckNextMethod();
									}
								}
								
	this.DetailsLoaded =	function(responseText)
							{
								UsageGadget.logger.LogMessage("INFO", "Getting usage info and passing it to the gadget to display!");
								try{
									var data = new DataToDisplay();
									var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
									var result = 1;

									var Usage = /<tr class=\"trStyleTotal\">[^`]+?<!-- total usage shown as bold -->[^`]+?>([0-9\-]+)<\/b>/i.exec(responseText);
									var Quota = /Monthly Allowance[^`]+?([0-9:]+\s*(?:G|M|h))/i.exec(responseText);
									var Period = /<tbody>[^`]+?<!-- date column -->[^`]+?>([0-9]{2} [A-Za-z]{3} [0-9]{4})<[^`]+>([0-9]{2} [A-Za-z]{3} [0-9]{4})[^`]+<\/tbody>/i.exec(responseText);
	
									if(Usage != null)
										data.totalUsage = (Usage[1] == '-' ? 0 : Usage[1]);
									else
										result = 0;

									if(Quota != null){
										var allowanceDetails = /([0-9]+)\s*(G|M)/.exec(Quota[1]);
										data.allowance = allowanceDetails[1] * (allowanceDetails[2] == 'G' ? 1000 : 1);
									}else
										result = 0;

									if(Period != null){
										var startParts = /([0-9]+) ([a-z]+)/i.exec(Period[1]);
										var endParts = /([0-9]+) ([a-z]+)/i.exec(Period[2]);
										
										if(monthNames[(new Date()).getMonth()] == 'Jan' && startParts[2] == 'Dec'){
											startParts.push((new Date()).getFullYear() - 1);
										}else{
											startParts.push((new Date()).getFullYear());
										}
										
										if(monthNames[(new Date()).getMonth()] == 'Dec' && endParts[2] == 'Jan'){
											endParts.push((new Date()).getFullYear() + 1);	
										}else{
											endParts.push((new Date()).getFullYear());
										}

										data.startDate = (new Date(startParts[1] + " " + startParts[2] + " " + startParts[3])).getTime();
										data.endDate = (new Date(endParts[1] + " " + endParts[2] + " " + endParts[3])).getTime();
									}else
										result = 0;

									if(result == 0){
										UsageGadget.logger.LogMessage("WARNING", "Required usage information wasn't found. Page is probably not compatible with method " + this.name + ". Trying next method.");
										UsageGadget.CheckNextMethod();
										return;
									}

									data.unratedUsage = 0;
									
									try{
										var UnratedUsage = /<tr class="trStyleTotal">[^`]+<td>([^`]+)<\/td>[^`]+?<\/tr>[^`]+?<\/tfoot>/i.exec(responseText);
										data.unratedUsage = UnratedUsage[1];
									}catch(err){
									}

									data.flyoutData = this.BuildFlyoutPage(responseText, data);
									data.raw = responseText;
									UsageGadget.DisplayData(data);
								}catch(err){
									UsageGadget.logger.LogMessage("ERROR", "Error getting the usage data. Message: " + err.message);
									UsageGadget.CheckNextMethod();
								}
							}
	
	this.BuildFlyoutPage = 	function (content, data)
							{
								try{
									content = content.replace(/\/res\/images/gi, "img");
		
									var pageTable = /<h5>Volume based usage meter table<\/h5>[\s]*(<table class[^`]+?>[^`]+<\/table>)/.exec(content);
									
									var accountDetails = /<table[^`]+?>([^`]+?Monthly Allowance[^`]+?)<\/table>/i.exec(content);
									accountDetails[1] = accountDetails[1].replace(/<a[^`]+?<\/a>/gi, "");
									accountDetails[1] = accountDetails[1].replace(/class="[^`]+?"/gi, "");
									accountDetails[1] = "<table class=\"accountTable\">" + accountDetails[1] + "</table>";

									var pageHTML = "<h5>PLAN DETAILS</h5>" + accountDetails[1] + "<div class=\"spacer\"></div>" + pageTable[1];
									
									return pageHTML;
								}catch(err){
									return '';	
								}
							}
}