// This file was generated by Dashcode from Apple Computer, Inc.
// You may edit this file to customize your Dashboard widget.

var DEBUG_LEVEL = 10;

// Constants (we hope)
var msPerSecond = 1000;
var sPerMinute  = 60;
var sPerHour    = 60 * sPerMinute;
var sPerDay     = 24 * sPerHour;

// Properties set by attributes panel
var targetKind;
var countdownTarget;
var wantLeadingZeros;
var wantBlinkingColons;
var wantStopAtZero;
var doAction;
var zeroAction;
var iCalEventURL = "__iCalEvent__.ics";
var iCalEventSummary;
var sharediCalURL;

// JavaScript interval timer
var updateTimerDisplayInterval;

// Clock registers
var currentTime;
var remainingSeconds;
var remainingTime = new Array(4);
var iCalendar;

// Flag for whether we've reached/passed the target time
var isTargetReached = false;

function DateToJulian(y, m, d) 
// RV returns Julian Day
{
   	var Y = y;
   	if (Y < 0) { Y = Y + 1};
   	var M = m;
   	var D = d;
   	if (M<3)	{
		Y--;
		M += 12;
	}
	
	var A = Math.floor(Y/100);
	var B = Math.floor(A/4);
	var C = 2 - A + B;
	var E = Math.floor(365.25*(Y + 4716));
	var F = Math.floor(30.6001*(M + 1));
	var julianday = C + eval(D) + E + F - 1524;
	return julianday;
   
}


function dprint(level, str) {
    if (level <= DEBUG_LEVEL) {
        alert(str);
    }
}

function load()
{
	setupParts();

	// Localize text
	var localizedElements = { "label-days":    "DAYS",
							  "label-hours":   "HOURS",
							  "label-minutes": "MIN",
							  "label-seconds": "SEC" };
	for (var anElement in localizedElements) {
		setElementText(anElement, getLocalizedString(localizedElements[anElement]));
	}

	// Get the properties
	targetKind         = +attributes.targetKind;
	wantLeadingZeros   = attributes.showLeadingZeros == 1;
	wantBlinkingColons = attributes.blinkSeparators == 1;
	wantStopAtZero     = attributes.reachedActionIndex == 0;
	doAction           = attributes.doAction == 1;
	zeroAction         = attributes.zeroAction;
	iCalEventSummary   = attributes.iCalEventSummary;
	sharediCalURL      = attributes.sharediCalURL;
	setCountdownTarget({ eventTime: attributes.targetDateTime,
	                     eventLabel: null });

	// Fix up URL
	if (sharediCalURL && sharediCalURL.length) {
		sharediCalURL = sharediCalURL.replace(/^webcal:\/\//, "http://");
	}

	// Make sure the alarm will run if necessary
	isTargetReached = false;
	
    if (targetKind == 0) {
		// Just start the timer now
		startDisplayUpdateTimer();
    } else if (targetKind == 1 && iCalEventSummary) {
        // Single iCal event but still pointing to an URL
		loadRemoteiCalEvents(startDisplayUpdateTimer, iCalEventURL);
    } else if (targetKind == 2 && sharediCalURL) {
        // If we're using remote events, load them and use the callback to start the timer
		loadRemoteiCalEvents(startDisplayUpdateTimer, sharediCalURL);
	}
}

function loadRemoteiCalEvents(callback, iCalURL)
{
	var xml_request = new XMLHttpRequest();
	xml_request.open("GET", iCalURL, true);
	
	xml_request.onreadystatechange = function () {
		if (xml_request.readyState == 4) {
			iCalendar = (new ICSParser()).parse(xml_request.responseText);
			setNextCountdownTarget();
			// Fire the callback event, if necessary
			if (callback != null) {
				callback();
			}
		}
	};
	
	xml_request.send(null);
}

// Set the timer
function setCountdownTarget(countdownEvent)
{
	countdownTarget = countdownEvent;
	if (countdownEvent.eventLabel != null) {
		setEventLabel(countdownEvent.eventLabel);
	}
}

// Find the next event in the event list and set the timer
function setNextCountdownTarget()
{
	updateCurrentTime();

	var nextEvent;
    if (iCalendar != null) {
        nextEvent = iCalendar[0].nextEvent();
    }
	
	if (nextEvent != null) {
		setCountdownTarget({ eventTime: nextEvent.nextOccurrence, eventLabel: nextEvent.summary });
		isTargetReached = false;
	}
}

function setEventLabel(label) {
	var eventLabel = document.getElementById("event-label");
	if (eventLabel) {
		var formatString = getLocalizedString("Countdown to %s");
		var labelString = formatString.replace("%s", label);
		eventLabel.innerText = labelString;
	}
}

// Install the interval timer
function startDisplayUpdateTimer()
{
	updateTimerDisplay();

	if (!updateTimerDisplayInterval)
		updateTimerDisplayInterval = setInterval(updateTimerDisplay, 1000);
}

// Remove the interval timer
function stopDisplayUpdateTimer()
{
	if (updateTimerDisplayInterval) {
		clearInterval(updateTimerDisplayInterval);
		updateTimerDisplayInterval = null;
	}
}

// Calculate and display the time
function updateTimerDisplay()
{
	calculateRemainingTime();
	
	setElementText("remaining-days",    remainingTime[0]);
	setElementText("remaining-hours",   formatTwoDigits(remainingTime[1]));
	setElementText("remaining-minutes", formatTwoDigits(remainingTime[2]));
	setElementText("remaining-seconds", formatTwoDigits(remainingTime[3]));

	var isVisible = true;
	if (wantBlinkingColons) {
		var isVisible = Math.floor(currentTime / 1000) % 2 ? "hidden" : "visible";
	}
	var colonDiv = document.getElementById("timer-colons");
	if (colonDiv)
		colonDiv.style.visibility = isVisible;

	// Check for alarm
	if (remainingSeconds <= 0) {
		// We're there
		if (isTargetReached == false) {
			// Just once
			isTargetReached = true;
			// Call the alarm hook
			if (doAction && zeroAction) {
				try {
					eval(zeroAction);
				}
				catch (exception) {
					alert(exception);
				}
			}
			// Start countdown to the next event
			setNextCountdownTarget();
		}
	}
}

// Set the contents of an HTML div
function setElementText(elementName, elementValue)
{
	var element = document.getElementById(elementName);
	if (element) {
		element.innerText = elementValue;
	}
}

// Format a number as one or two digits
function formatTwoDigits(aNumber)
{
	var digits = aNumber.toString(10);

	// Add a leading zero if it's only one digit long
	if (wantLeadingZeros && digits.length == 1) {
		digits = "0" + digits;
	}
	
	return digits;
}

// Store the current time in the clock's internal state
function updateCurrentTime()
{
	currentTime = new Date();
}

// Returns [days, hours, minutes, seconds]
function calculateRemainingTime()
{
	// Start by getting the current date
	updateCurrentTime();
	// Clear excessive precision
	currentTime.setMilliseconds(0);

	// Number of seconds between now and target
	remainingSeconds = Math.floor((countdownTarget.eventTime.getTime() - currentTime.getTime()) / msPerSecond);
	if (remainingSeconds <= 0) {
		if (wantStopAtZero) {
			remainingSeconds = 0;
		}
		else {
			remainingSeconds = Math.abs(remainingSeconds);
		}
	}
	
	// Calculate days
	var remainingDays = Math.floor(remainingSeconds / sPerDay);
	// And take remainder
    var leftoverSeconds = remainingSeconds - remainingDays * sPerDay;
    // Same for hours, minutes, and seconds
	var remainingHours = Math.floor(leftoverSeconds / sPerHour);
    leftoverSeconds -= remainingHours * sPerHour;
	var remainingMinutes = Math.floor(leftoverSeconds / sPerMinute);
    leftoverSeconds -= remainingMinutes * sPerMinute;

	remainingTime[0] = remainingDays;
	remainingTime[1] = remainingHours;
	remainingTime[2] = remainingMinutes;
	remainingTime[3] = leftoverSeconds;
}

function remove()
{
	// your widget has just been removed from the layer
	// remove any preferences as needed
	// widget.setPreferenceForKey(null, createInstancePreferenceKey("your-key"));
	stopDisplayUpdateTimer();
}

function hide()
{
	// your widget has just been hidden stop any timers to
	// prevent cpu usage
	stopDisplayUpdateTimer();
}

function show()
{
	// your widget has just been shown.  restart any timers
	// and adjust your interface as needed
	startDisplayUpdateTimer();
	
	daysigns = new Array(20);
	daysigns[0] = 20;
	daysigns[1]  = "Imix";
	daysigns[2]  = "Ik";  
	daysigns[3]  = "Ak'bal";
	daysigns[4]  = "K'an";
	daysigns[5]  = "Chikchan";
	daysigns[6]  = "Kimi";
	daysigns[7]  = "Manik'";
	daysigns[8]  = "Lamat";
	daysigns[9]  = "Muluk'";
	daysigns[10] = "Ok";   
	daysigns[11] = "Chuen";
	daysigns[12] = "Eb";
	daysigns[13] = "Ben";  
	daysigns[14] = "Ix"; 
	daysigns[15] = "Men";
	daysigns[16] = "Kib";
	daysigns[17] = "Kaban";  
	daysigns[18] = "Etz'nab";
	daysigns[19] = "Kawak";   
	daysigns[20] = "Ahaw";

	daysignsf = new Array(20);
	daysignsf[0] = 20;	
	daysignsf[1]  = "imix";
	daysignsf[2]  = "ik";  
	daysignsf[3]  = "akbal";
	daysignsf[4]  = "kan";
	daysignsf[5]  = "chikchan";
	daysignsf[6]  = "kimi";
	daysignsf[7]  = "manik";
	daysignsf[8]  = "lamat";
	daysignsf[9]  = "muluk";
	daysignsf[10] = "ok";   
	daysignsf[11] = "chuen";
	daysignsf[12] = "eb";
	daysignsf[13] = "ben";  
	daysignsf[14] = "ix"; 
	daysignsf[15] = "men";
	daysignsf[16] = "kib";
	daysignsf[17] = "kaban";  
	daysignsf[18] = "etznab";
	daysignsf[19] = "kawak";   
	daysignsf[20] = "ahaw";
	
	meztli = new Array(20);
	meztli[0] = 19;	
	meztli[1]  = "Pop";	       
	meztli[2]  = "Wo";   
	meztli[3]  = "Sip";
	meztli[4]  = "Sotz'";    
	meztli[5]  = "Sek";    
	meztli[6]  = "Xul";
	meztli[7]  = "Yaxk'in";   
	meztli[8]  = "Mol"; 
	meztli[9]  = "Ch'en";
	meztli[10] = "Yax";   
	meztli[11] = "Sak";     
	meztli[12] = "Keh";
	meztli[13] = "Mak";       
	meztli[14] = "K'ank'in";     
	meztli[15] = "Muan";
	meztli[16] = "Pax";
	meztli[17] = "Kayab";       
	meztli[18] = "Kumk'u";
	meztli[19] = "Wayeb";   
	
	meztlif = new Array(20);
	meztlif[0] = 19;
	meztlif[1]  = "pop";	       
	meztlif[2]  = "wo";   
	meztlif[3]  = "sip";
	meztlif[4]  = "sotz'";    
	meztlif[5]  = "sek";    
	meztlif[6]  = "xul";
	meztlif[7]  = "yaxkin";   
	meztlif[8]  = "mol"; 
	meztlif[9]  = "chen";
	meztlif[10] = "yax";   
	meztlif[11] = "sak";     
	meztlif[12] = "keh";
	meztlif[13] = "mak";       
	meztlif[14] = "kankin";     
	meztlif[15] = "muan";
	meztlif[16] = "pax";
	meztlif[17] = "kayab";       
	meztlif[18] = "kumku";
	meztlif[19] = "wayeb"; 
	
	
	var today = new Date();
	year = today.getYear(); if (year < 1900) { year = year + 1900};
	month = today.getMonth();
	date = today.getDate();
	hour = today.getHours();

	var julday = DateToJulian (year, month + 1, date);
	var daysum = julday + 5757;
	var tonalnum = ((daysum - 6) % 13) + 1;
	var tonalname = ((daysum - 1) % 20) + 1;

	var xihuitltemp = (daysum + 148) % 365;
	var meztliname = Math.floor((xihuitltemp) / 20)+1;
	var meztlinum = (xihuitltemp) % 20;

	var lctemp = julday - 584283;   
	var baktun = Math.floor(lctemp / 144000);
	lctemp = lctemp - baktun * 144000;
	var katun = Math.floor(lctemp / 7200);
	lctemp = lctemp - katun * 7200;
	var tun = Math.floor(lctemp / 360);
	lctemp = lctemp - tun * 360;
	var uinal = Math.floor(lctemp / 20);
	var kin = lctemp - uinal * 20;
	
	lcnum.innerText= ""+baktun+"."+katun+"."+tun+"."+uinal+"."+kin+"";
	crval.innerText= ""+tonalnum+" "+daysigns[tonalname]+" "+meztlinum+" "+meztli[meztliname];
	
	sisig.style.background='url(Images/isig-'+meztliname+'.png)';
	sbaktun.style.background='url(Images/baktun-'+baktun+'.png)';
	skatun.style.background='url(Images/katun-'+katun+'.png)';
	stun.style.background='url(Images/tun-'+tun+'.png)';
	swinal.style.background='url(Images/winal-'+uinal+'.png)';
	skin.style.background='url(Images/kin-'+kin+'.png)';
	
    daynum.style.background='url(Images/'+tonalnum+'.png) no-repeat top left';
	metzlinum.style.background='url(Images/'+meztlinum+'.png) no-repeat top left';	
	
	var tonalaffix ="";
	switch (tonalnum) {
		case  6:
		case  7:
		case  8:
		case  9:
		case 10:
			tonalaffix ="-2";
			break;
		case 11:
		case 12:
		case 13:
			tonalaffix ="-3";
			break;
	} 
	daysign.style.background='url(Images/'+daysignsf[tonalname]+tonalaffix+'.png) no-repeat top right';

	meztliaffix ="";
	switch (meztlinum) {
		case  0:
			meztliaffix ="-3";
		break;
		case  6:
		case  7:
		case  8:
		case  9:
		case 10:
			meztliaffix ="-2";
			break;
		case 11:
		case 12:
		case 13:
		case 14:
		case 15:
			meztliaffix ="-3";
			break;
		case 16:
		case 17:
		case 18:
		case 19:
			meztliaffix ="-4";
			break;   
	} 
	metzlisign.style.background='url(Images/'+meztlif[meztliname]+meztliaffix+'.png) no-repeat top right';
	
}

function showBack(event)
{
	// your widget needs to show the back

	var front = document.getElementById("front");
	var back = document.getElementById("back");

	if (window.widget)
		widget.prepareForTransition("ToBack");

	// stopDisplayUpdateTimer();

	front.style.display="none";
	back.style.display="block";
	
	if (window.widget)
		setTimeout('widget.performTransition();', 0);
}

function showFront(event)
{
	// your widget needs to show the front

	var front = document.getElementById("front");
	var back = document.getElementById("back");

	if (window.widget)
		widget.prepareForTransition("ToFront");

	front.style.display="block";
	back.style.display="none";

	//startDisplayUpdateTimer();
	
	if (window.widget)
		setTimeout('widget.performTransition();', 0);
}

if (window.widget)
{
	widget.onremove = remove;
	widget.onhide = hide;
	widget.onshow = show;
}

function doubleClickTimer(event) 
{
	if (event.altKey) {
		// loadDemoEventList();
	}
}

function rvtunderline (object) 
{
	object.style.textDecoration='underline';
	object.style.cursor="pointer";
}

function rvtclear (object) 
{
	object.style.textDecoration='none';
}


