// -*-java-*-
// ***************************************************************************************
// Countdown graphically
// ***************************************************************************************
// Version 0.3
//
// Usage: Include this library at the beginning of the document (head section)
// <script language="JavaScript" src="pinuts-countdown.js" type="text/javascript"></script>


// Setup, used in Construction only, use it for different counters...
var cd_colon = "colon.gif";   // Picture of the field seperator
var cd_milli = "milli.gif";   // Fake animation of milliseconds
var cd_milli_stop = "millistop.gif"  // Picture of 'haltet' Milliseconds (000)
var cd_img_prefix = "js_pix/";       // prefix of 0..9 images
var cd_img_suffix = "gif"     // guess what
var cd_show_ms = 1;           // Really show ms-Counter

// Instance-administration
var cd_instances = new Array();       // Array of Instances
var cd_instances_hours = new Array(); // Hour-based counters
var cd_instances_dates = new Array(); // Date-based counters
var cd_tick_running = 0;
var cd_tick_mutex = 0;                // Paranoia: let cd_tick run mutexed

// Local Variables
var cd_ims = new Array();         // Array of images (per instance)
var cd_prefix = new Array();      // Prefix for document.image objects (per instance)
var cd_then = new Array();        // Target timestamps (per instance)

// Get new instance
function cd_new() {
    var l = cd_instances.length;
    cd_instances[l] = l;
    return l;
}

// Pads integer i to be a len long string, right padded with char
// String is cut to show last len chars of string
function cd_pad(i, len, pad_char) {
    var str = ""+(isNaN(i)?"0":i);

    if (str.length <= len) {
	while( str.length < len ) {
	    str = pad_char + str;
	}
    } else {
	str = str.substr( str.length-len-1  , str.length-1)
    }
    return str;
}

// General tick function
function cd_tick() {

    if (cd_tick_mutex)
	return;

    // Critical Block
    cd_tick_mutex = 42;

    var now = new Date();
    var w;
    var diff;
    var str;
    var i;

    // Traverse Hour-based counters
    for (w = 0; w < cd_instances_hours.length; w++) {
	var id = cd_instances_hours[w];
	diff = cd_then[id].getTime() - now.getTime() - (now.getTimezoneOffset()*60*1000);
	if ( diff < 0 ) {
	    diff = 0;
	}

	// Compute String hhhh:mm:ss
	var i = parseInt(diff / 1000);  // secs
	var s = parseInt(i % 60);
	i     = parseInt(i / 60);       // minutes
	var m = parseInt(i % 60);
	i     = parseInt(i / 60);       // hours
	var h = i;

	str = cd_pad(h, 4, '0');
	str+= cd_pad(m, 2, '0');
	str+= cd_pad(s, 2, '0');

	for (i = 0; i<8; i++) {
	    var im = cd_ims[id][str.charAt(i) - '0'];
	    if ( im ) {
		document.images[cd_prefix[id]+i].src = cd_ims[id][str.charAt(i) - '0'].src;
	    } else {
		window.status = "(Hourcountdown) No Image for: "+str.charAt(i);
	    }
	}

	if ( diff == 0 ) {
	    // Time is up, disable fake millisecond counter
	    document.images[cd_prefix[id]+'m'].src = cd_img_prefix+cd_milli_stop;
	}

    }

    // Traverse Date-based counters
    for (w = 0; w < cd_instances_dates.length; w++) {
	var id = cd_instances_dates[w];
	diff = cd_then[id].getTime() - now.getTime() - (now.getTimezoneOffset()*60*1000);
	if ( diff < 0 ) {
	    diff = 0;
	}

	// Compute YYYY:MM:DD:hh:mm:ss
	var i = parseInt(diff / 1000);  // secs
	var s = parseInt(i % 60);
	i     = parseInt(i / 60);       // minutes
	var m = parseInt(i % 60);
	i     = parseInt(i / 60);       // hours
	var h = parseInt(i % 24);
	i     = parseInt(i / 24);       // Days
	var D = parseInt(i % 30);
	i     = parseInt(i / 30);       // Months
	var M = parseInt(i % 12);
	i     = parseInt(i / 12);       // Years left
	var Y = i;

	str = cd_pad(Y, 4, '0');
	str+= cd_pad(M, 2, '0');
	str+= cd_pad(D, 2, '0');
	str+= cd_pad(h, 2, '0');
	str+= cd_pad(m, 2, '0');
	str+= cd_pad(s, 2, '0');
	
	for (i = 0; i<14; i++) {
	    var im = cd_ims[id][str.charAt(i) - '0'];
	    if ( im ) {
		document.images[cd_prefix[id]+i].src = cd_ims[id][str.charAt(i) - '0'].src;
	    } else {
		window.status="(Datecountdown) No Image for: "+str.charAt(i);
	    }
	}

	if ( diff == 0 ) {
	    // Time is up, disable fake millisecond counter
	    document.images[cd_prefix[id]+'m'].src = cd_img_prefix+cd_milli_stop;
	}

    }

    // Critical Block end
    cd_tick_mutex = 0;
}

// Generate image-Tags for hour-based countdown: hhhh:mm:ss
// Last 2 arguments are width and height of images
function cd_countdown_hours(year, month, day, hour, min, sec, w, h) {

    // Create Instance and symbol
    var id = cd_new();
    cd_instances_hours[cd_instances_hours.length] = id;
    cd_then[id] = new Date(year,month-1,day,hour,min,sec);
        
    // Preload Images
    cd_ims[id] = preload_range(cd_img_prefix,0,10,1,cd_img_suffix);
    cd_ims[id] = preload_picture(cd_ims[id], cd_img_prefix+cd_colon);
    cd_ims[id] = preload_picture(cd_ims[id], cd_img_prefix+cd_milli);
    cd_ims[id] = preload_picture(cd_ims[id], cd_img_prefix+cd_milli_stop);

    // Create prefix
    var prefix = 'cd'+id;
    cd_prefix[id] = prefix;

    // Hours
    document.write(img_tag('',prefix+'0', w, h));
    document.write(img_tag('',prefix+'1', w, h));
    document.write(img_tag('',prefix+'2', w, h));
    document.write(img_tag('',prefix+'3', w, h));
    document.write(img_tag(cd_img_prefix+cd_colon,null,w,h));
    // Minutes
    document.write(img_tag('',prefix+'4', w, h));
    document.write(img_tag('',prefix+'5', w, h));
    document.write(img_tag(cd_img_prefix+cd_colon,null,w,h));
    // Seconds
    document.write(img_tag('',prefix+'6', w, h));
    document.write(img_tag('',prefix+'7', w, h));
    // "Milliseconds"
    if (cd_show_ms) {
	document.write(img_tag(cd_img_prefix+cd_colon,null,w,h));
	document.write(img_tag(cd_img_prefix+cd_milli,prefix+'m',w*3,h));
    }

    // Display once and start
    cd_tick();
    if (!cd_tick_running) {
	window.setInterval("cd_tick();", 1000);
    }
    return id;
}


// Date-type Countdown: yyyy:mm:dd:hh:mm:ss
// This one is consideren harmful...
//

function cd_countdown_date(year, month, day, hour, min, sec, w, h) {

    // Create Instance and symbol
    var id = cd_new();
    cd_instances_dates[cd_instances_dates.length] = id;
    cd_then[id] = new Date(year,month-1,day,hour,min,sec);
    
    // Preload Images
    cd_ims[id] = preload_range(cd_img_prefix,0,10,1,cd_img_suffix);
    cd_ims[id] = preload_picture(cd_ims[id], cd_colon);
    cd_ims[id] = preload_picture(cd_ims[id], cd_img_prefix+cd_milli);
    cd_ims[id] = preload_picture(cd_ims[id], cd_img_prefix+cd_milli_stop);

    // Create prefix
    var prefix = 'cd'+id;
    cd_prefix[id] = prefix;

    // Year
    document.write(img_tag('',prefix+'0',w,h));
    document.write(img_tag('',prefix+'1',w,h));
    document.write(img_tag('',prefix+'2',w,h));
    document.write(img_tag('',prefix+'3',w,h));
    document.write(img_tag(cd_img_prefix+cd_colon,null,w,h));
    // Month
    document.write(img_tag('',prefix+'4',w,h));
    document.write(img_tag('',prefix+'5',w,h));
    document.write(img_tag(cd_img_prefix+cd_colon,null,w,h));
    // Day
    document.write(img_tag('',prefix+'6',w,h));
    document.write(img_tag('',prefix+'7',w,h));
    document.write(img_tag(cd_img_prefix+cd_colon,null,w,h));
    // Hours
    document.write(img_tag('',prefix+'8',w,h));
    document.write(img_tag('',prefix+'9',w,h));
    document.write(img_tag(cd_img_prefix+cd_colon,null,w,h));
    // Minutes
    document.write(img_tag('',prefix+'10',w,h));
    document.write(img_tag('',prefix+'11',w,h));
    document.write(img_tag(cd_img_prefix+cd_colon,null,w,h));
    // Seconds
    document.write(img_tag('',prefix+'12',w,h));
    document.write(img_tag('',prefix+'13',w,h));
    // "Milliseconds"
    if (cd_show_ms) {
	document.write(img_tag(cd_img_prefix+cd_colon,null,w,h));
	document.write(img_tag(cd_img_prefix+cd_milli,prefix+'m',w*3,h));
    }

    // Draw and start
    cd_tick;
    if (!cd_tick_running) {
	window.setInterval("cd_tick();", 1000);
    }
    return id;
}

