window.CoolClock = function(canvasId,displayRadius,skinId,showSecondHand,gmtOffset,Bh,Bm,Bs)
{
	return this.init(canvasId,displayRadius,skinId,showSecondHand,gmtOffset,Bh,Bm,Bs);
}

CoolClock.findAndCreateClocks = function()
{
	var canvases = document.getElementsByTagName("canvas");
	for (var i=0;i<canvases.length;i++)
    {
		var fields = canvases[i].className.split(" ")[0].split(":");
		if (fields[0] == "CoolClock")
        {
			new CoolClock(canvases[i].id,fields[2],fields[1],fields[3]!="noSeconds",fields[4],fields[5],fields[6],fields[7]);
		}
	}
}

// borrowed from behaviour.js
// actually doesn't work right unless it's at the end of html document
// hence can't have a body onload
// this is a bug. FIXME
// maybe have a setTimeout hack??
CoolClock.addLoadEvent = function(func)
{
	var oldonload = window.onload;
	if (typeof window.onload != 'function')
		window.onload = func;
	else
		window.onload = function()
        {
			oldonload();
			func();
		}
}

CoolClock.config =
{
	clockTracker: {},
	tickDelay: 1000,
	longTickDelay: 1000,
	defaultRadius: 85,
	renderRadius: 100,
	defaultSkin: "swissRail",
	skins:
    {

		swissRail:
        {
			outerBorder: { lineWidth: 0, radius:95, color: "black", alpha: 0 },
			smallIndicator: { lineWidth: 2, startAt: 89, endAt: 91, color: "black", alpha: 1 },
			largeIndicator: { lineWidth: 5, startAt: 80, endAt: 94, color: "black", alpha: 1 },
			hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "black", alpha: 1 },
			minuteHand: { lineWidth: 7, startAt: -15, endAt: 75, color: "black", alpha: 1 },
			secondHand: { lineWidth: 1, startAt: -20, endAt: 85, color: "red", alpha: 0 },
			secondDecoration: { lineWidth: 1, startAt: 70, radius: 4, fillColor: "red", color: "red", alpha: 0 }
		}

	}
};

CoolClock.prototype =
{
	init: function(canvasId,displayRadius,skinId,showSecondHand,gmtOffset,Bh,Bm,Bs)
    {
        this.Bh=parseInt(Bh);
        this.Bm=parseInt(Bm);
        this.Bs=parseInt(Bs);


        this.canvasId = canvasId;
		this.displayRadius = displayRadius || CoolClock.config.defaultRadius;
		this.skinId = skinId || CoolClock.config.defaultSkin;
		this.showSecondHand = typeof showSecondHand == "boolean" ? showSecondHand : true;
		this.tickDelay = CoolClock.config[ this.showSecondHand ? "tickDelay" : "longTickDelay"];

		this.canvas = document.getElementById(canvasId);

		this.canvas.setAttribute("width",this.displayRadius*2);
		this.canvas.setAttribute("height",this.displayRadius*2);

		this.canvas.style.width = this.displayRadius*2 + "px";
		this.canvas.style.height = this.displayRadius*2 + "px";

		this.renderRadius = CoolClock.config.renderRadius; 

		this.scale = this.displayRadius / this.renderRadius;
		this.ctx = this.canvas.getContext("2d");
		this.ctx.scale(this.scale,this.scale);

		this.gmtOffset = gmtOffset != null ? parseFloat(gmtOffset) : gmtOffset;

		CoolClock.config.clockTracker[canvasId] = this;
		this.tick();
		return this;
	},

	fullCircle: function(skin) {
		this.fullCircleAt(this.renderRadius,this.renderRadius,skin);
	},

	fullCircleAt: function(x,y,skin) {
		with (this.ctx) {
			save();
			globalAlpha = skin.alpha;
			lineWidth = skin.lineWidth;
			if (!document.all)
				beginPath();
			if (document.all)
				// excanvas doesn't scale line width so we will do it here
				lineWidth = lineWidth * this.scale;
			arc(x, y, skin.radius, 0, 2*Math.PI, false);
			if (document.all)
				// excanvas doesn't close the circle so let's color in the gap
				arc(x, y, skin.radius, -0.1, 0.1, false);
			if (skin.fillColor) {
				fillStyle = skin.fillColor
				fill();
			}
			else {
				// XXX why not stroke and fill
				strokeStyle = skin.color;
				stroke();
			}
			restore();
		}
	},

	radialLineAtAngle: function(angleFraction,skin)
    {
		with (this.ctx) {
			save();
			translate(this.renderRadius,this.renderRadius);
			rotate(Math.PI * (2 * angleFraction - 0.5));
			globalAlpha = skin.alpha;
			strokeStyle = skin.color;
			lineWidth = skin.lineWidth;
			if (document.all)
				// excanvas doesn't scale line width so we will do it here
				lineWidth = lineWidth * this.scale;
			if (skin.radius) {
				this.fullCircleAt(skin.startAt,0,skin)
			}
			else {
				beginPath();
				moveTo(skin.startAt,0)
				lineTo(skin.endAt,0);
				stroke();
			}
			restore();
		}
	},

	render: function(hour,min,sec)
    {
        var skin = CoolClock.config.skins[this.skinId];
		this.ctx.clearRect(0,0,this.renderRadius*2,this.renderRadius*2);

		this.fullCircle(skin.outerBorder);

		for (var i=0;i<60;i++)
			this.radialLineAtAngle(i/60,skin[ i%5 ? "smallIndicator" : "largeIndicator"]);

		this.radialLineAtAngle((hour+min/60)/12,skin.hourHand);
		this.radialLineAtAngle((min+sec/60)/60,skin.minuteHand);
		if (this.showSecondHand) {
			this.radialLineAtAngle(sec/60,skin.secondHand);
			if (!document.all)
				// decoration doesn't render right in IE so lets turn it off
				this.radialLineAtAngle(sec/60,skin.secondDecoration);
		}
	},


	nextTick: function()
    {
		setTimeout("CoolClock.config.clockTracker['"+this.canvasId+"'].tick()",this.tickDelay);
	},

	stillHere: function()
    {
		return document.getElementById(this.canvasId) != null;
	},

	refreshDisplay: function()
    {

		if (this.gmtOffset != null)
        {
            if(this.Bs > 59)
            {
              this.Bs=0;
              this.Bm++;

              if(this.Bm > 59)
              {
                this.Bm==0;
                this.Bh++;

                if(this.Bh>12)
                  this.Bh-=12;
              }
            }
            else
            {
              this.Bs++;
            }

            //this.render(parseInt(this.Bh), parseInt(this.Bm), parseInt(this.Bs));
            this.render(this.Bh, this.Bm, this.Bs);
		}
		else
        {

		}
	},

	tick: function()
    {
		if (this.stillHere()) {
			this.refreshDisplay()
			this.nextTick();
		}
	}
}

CoolClock.addLoadEvent(CoolClock.findAndCreateClocks);