/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.Clock");

dojo.require("dojo.widget.*");
dojo.require("dojo.gfx.*");
dojo.require("dojo.uri.Uri");
dojo.require("dojo.lang.common");
dojo.require("dojo.lang.timing.Timer");

dojo.widget.defineWidget(
	"dojo.widget.Clock",
	dojo.widget.HtmlWidget,
	function(){
		// summary: A basic clock that supports offset and labels
		// description:
		//		Uses SVG and Internet Explorer's VML implementation to render a clock
		//		using the gfx module.
		// timeZoneOffset: Integer
		//		Amount (in hours) to offset the clock, relative to local time.
		// date: Date
		// image: String
		//		Location of the background image
		var self=this;
		this.timeZoneOffset=0;	//	this is fun.
		this.label="";		//	optional label.

		this.date=new Date();

		this.handColor="#788598";
		this.handStroke="#6f7b8c";
	//	this.secondHandColor="#c90405";
		this.secondHandColor=[201, 4, 5, 0.8];
		this.topLabelColor="#efefef";
		this.labelColor="#fff";

		//	timer
		this.timer = new dojo.lang.timing.Timer(1000);

		//	shapes
		this.center={ x:75, y:75 };
		this.hands={
			hour:null,
			minute:null,
			second:null
		};
		this.shadows={
			hour:{ shadow:null, shift:{ dx:2, dy:2} },
			minute:{ shadow:null, shift:{ dx:2, dy:3} },
			second:{ shadow:null, shift:{ dx:4, dy:4} }
		};
		this.image = dojo.uri.dojoUri("src/widget/templates/images/clock.png");
		this.surface=null;
		this.labelNode=null;
		this.topLabelNode=null;

		this.draw=function(){
			//	summary: Moves the hands of the clock to the proper position based on the current date.
			self.date=new Date();
			var h=(self.date.getHours()+self.timeZoneOffset) % 12;
			var m=self.date.getMinutes();
			var s=self.date.getSeconds();

			self.placeHour(h, m, s);
			self.placeMinute(m, s);
			self.placeSecond(s);

			self.topLabelNode.innerHTML=((self.date.getHours()+self.timeZoneOffset)>11)?"PM":"AM";
		};

		this.timer.onTick=self.draw;
	},
	{
		set:function(/* Date */dt){
			// summary: Set the date object manually
			this.date=dt;
			if(!this.timer.isRunning){
				this.draw();
			}
		},
		start:function(){
			// summary: start the clock.
			this.timer.start();
		},
		stop:function(){
			// summary: stop the clock.
			this.timer.stop();
		},

		_initPoly:function(parent, points){
			var path = parent.createPath();
			var first = true;
			dojo.lang.forEach(points, function(c){
				if(first){
					path.moveTo(c.x, c.y);
					first=false;
				} else {
					path.lineTo(c.x, c.y);
				}
			});
			return path;
		},
		_placeHand:function(shape, angle, shift){
			var move = { dx:this.center.x + (shift?shift.dx:0), dy:this.center.y+(shift?shift.dy:0) };
			return shape.setTransform([move, dojo.gfx.matrix.rotateg(-angle)]);
		},
		placeHour:function(/* Number */h, /* Number */m, /* number */s){
			// summary: place the hour hand at the proper point and rotation.
			var angle=30 *(h + m/60 + s/3600);
			this._placeHand(this.hands.hour, angle);
			this._placeHand(this.shadows.hour.shadow, angle, this.shadows.hour.shift);
		},
		placeMinute:function(/* Number */m, /* Number */s){
			// summary: place the minute hand at the proper point and rotation.
			var angle=6 * (m + s/60);
			this._placeHand(this.hands.minute, angle);
			this._placeHand(this.shadows.minute.shadow, angle, this.shadows.minute.shift);
		},
		placeSecond:function(/* Number */s){
			// summary: place the second hand at the proper point and rotation.
			var angle=6 * s;
			this._placeHand(this.hands.second, angle);
			this._placeHand(this.shadows.second.shadow, angle, this.shadows.second.shift);
		},

		init:function(){
			// summary: initialize the widget by creating the initial shapes.
			//	start by setting up the domNode
			if(this.domNode.style.position != "absolute"){
				this.domNode.style.position = "relative";
			}

			//	clean out any children
			while(this.domNode.childNodes.length>0){
				this.domNode.removeChild(this.domNode.childNodes[0]);
			}

			//	set ourselves up.
			this.domNode.style.width="150px";
			this.domNode.style.height="150px";

			this.surface=dojo.gfx.createSurface(this.domNode, 150, 150);
			this.surface.createRect({width: 150, height: 150});
			this.surface.createImage({width: 150, height: 150, src: this.image+""});

			var hP=[ {x: -3, y: -4}, {x: 3, y: -4}, {x: 1, y: -27}, { x:-1, y:-27}, {x: -3, y: -4} ];
			var mP=[ {x: -3, y: -4}, {x: 3, y: -4}, {x: 1, y: -38}, {x:-1, y:-38}, {x: -3, y: -4} ];
			var sP=[ {x: -2, y: -2}, {x: 2, y: -2}, {x: 1, y: -45}, {x: -1, y: -45}, {x: -2, y: -2} ];

			this.shadows.hour.shadow = this._initPoly(this.surface, hP)
				.setFill([0, 0, 0, 0.1]);
			this.hands.hour = this._initPoly(this.surface, hP)
				.setStroke({color: this.handStroke, width:1 })
				.setFill({
					type:"linear",
					x1:0, y1:0, x2:0, y2:-27,
					colors:[{offset:0, color:"#fff"}, {offset:0.33, color:this.handColor}]
				});
			this.shadows.minute.shadow = this._initPoly(this.surface, mP)
				.setFill([0, 0, 0, 0.1]);
			this.hands.minute = this._initPoly(this.surface, mP)
				.setStroke({color: this.handStroke, width:1 })
				.setFill({
					type:"linear",
					x1:0, y1:0, x2:0, y2:-38,
					colors:[{offset:0, color:"#fff"}, {offset:0.33, color:this.handColor}]
				});

			this.surface.createCircle({r: 6})
				.setStroke({color: this.handStroke, width:2 })
				.setFill("#fff")
				.setTransform({dx: 75, dy: 75});

			this.shadows.second.shadow = this._initPoly(this.surface, sP)
				.setFill([0, 0, 0, 0.1]);
			this.hands.second = this._initPoly(this.surface, sP)
				.setFill(this.secondHandColor);

			//	clock centers, doesn't move.
			this.surface.createCircle({r: 4})
				.setFill(this.secondHandColor)
				.setTransform({dx: 75, dy: 75});

			//	labels
			this.topLabelNode=document.createElement("div");
			with(this.topLabelNode.style){
				position="absolute";
				top="3px";
				left="0px";
				color=this.topLabelColor;
				textAlign="center";
				width="150px";
				fontFamily="sans-serif";
				fontSize="11px";
				textTransform="uppercase";
				fontWeight="bold";
			}
			this.topLabelNode.innerHTML=((this.date.getHours()+this.timeZoneOffset)>11)?"PM":"AM";
			this.domNode.appendChild(this.topLabelNode);

			this.labelNode=document.createElement("div");
			with(this.labelNode.style){
				position="absolute";
				top="134px";
				left="0px";
				color=this.labelColor;
				textAlign="center";
				width="150px";
				fontFamily="sans-serif";
				fontSize="10px";
				textTransform="uppercase";
				fontWeight="bold";
			}
			this.labelNode.innerHTML=this.label||"&nbsp;";
			this.domNode.appendChild(this.labelNode);

			this.draw();
		},
		postCreate:function(){
			// summary: Create the clock and start the timer.
			this.init();
			this.start();
		}
	}
);
