jQuery.fn.extend({
	timeRule: function (settings) {
		settings = jQuery.extend({
			DST: false,
			rules: jQuery.timeRule.makeRule(),
			GMT: -12,
			timeZone: 'EDT',
			parent: this,
			clockFormat: '{day}, {month} {date}, {year}<br />Our Time: {hour}:{min}:{sec} {ampm} {zone}'
		}, settings);
		
		jQuery.timeRule.settings = settings;
		
		jQuery.timeRule.run();
	}
});

jQuery.timeRule = {
	version: '1.0',
	setings: {},
	GMT: function() {
		var x = this.settings.GMT;
		function hToMSec(hour) {//Hours to Milliseconds
			return hour * 3600000;
		}
		if (!this.settings.DST) {
			x = x + 1;
		}
		x = x + 10;
		return hToMSec(x);
	},
	/* Year Functions */
	setYear: function(x) {
		return (x < 500) ? x + 1900 : x;
	},
	getYear: function() {
		return this.setYear(this.setDate().getYear());
	},
	/* Hour Functions */
	setHour: function(x) {
		if (x == 0) {x = 12;}
		return ((x > 12) ? x -= 12: x);
	},
	getHour: function() {
		return this.setHour(this.setDate().getHours());
	},
	/* AM & PM Functions */
	setAmPm: function(x) {
		return (x > 11)?'PM':'AM';
	},
	getAmPm: function() {
		return this.setAmPm(this.setDate().getHours());;
	},
	/* Minute & Second Functions  */
	getMin: function() {
		return this.setMinSec(this.setDate().getMinutes());
	},
	getSec: function() {
		return this.setMinSec(this.setDate().getSeconds());
	},
	setMinSec: function(x) {
		return (x > 9) ? x :'0' + x;
	},
	/* Date & Day Functions */
	d: new Date,//By declaring this as a global variable, we keep memory leaks at a minimum
	setDate: function() {
		this.d = new Date(); //This is where the date/time is updated -- VERY IMPORTANT
		this.d = new Date(
			this.d.getUTCFullYear(),
			this.d.getUTCMonth(),
			this.d.getUTCDate(),
			this.d.getUTCHours(),
			this.d.getUTCMinutes(),
			this.d.getUTCSeconds());

		this.d.setTime(this.d.getTime() - this.GMT());
		return this.d;
	},
	getDate: function() {
		return this.setDate().getDate();
	},
	getDay: function() {
		return ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'][this.setDate().getDay()];
	},
	/* Month Functions */
	getMonth: function() {
		return ['January','February','March','April','May','June','July','August','September','October','November','December'][this.setDate().getMonth()];
	},
	/* External Clock */
	clock: function() {
		return jQuery.timeRule.settings.clockFormat
			.replace(/{day}/g, this.getDay())
			.replace(/{month}/g, this.getMonth())
			.replace(/{date}/g, this.getDate())
			.replace(/{year}/g, this.getYear())
			.replace(/{hour}/g, this.getHour())
			.replace(/{min}/g, this.getMin())
			.replace(/{sec}/g, this.getSec())
			.replace(/{ampm}/g, this.getAmPm())
			.replace(/{zone}/g, this.settings.timeZone.toUpperCase());
	},
	dayRuler: function(day, rules, fn) {
		day = day.split('|');
		jQuery(day).each(function(h) {
			switch (day[h]) {
				case jQuery.timeRule.getDay():
					return jQuery.timeRule.timeRuler(rules, fn);
					break;
			}
		});
	},
	timeRuler: function (rules, fn) {
		var currentHour = this.getHour();
		var amPm = this.getAmPm();
		var rule = rules.split('|'); //rules = 3-4:PM|
		jQuery(rule).each(function(i) {
			var ruleDetails = rule[i].split(':');
			if (amPm == ruleDetails[1]) {
				if (ruleDetails[0].match('-')) {
					var hours = ruleDetails[0].split('-');
					if (currentHour >= hours[0] && currentHour <= hours[1]) {
						if (jQuery.isFunction(fn)) {
							fn();
						} else {
							return fn;
						}
					}
				} else {
					if (ruleDetails[0] == currentHour) {
						if (jQuery.isFunction(fn)) {
							fn();
						} else {
							return fn;
						}
					}
				}
			}
		});
	},
	makeRule: function(day, time, fn) {
		return [
			(day 	? day 	: 'Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday'),//Default is every day
			(time 	? time 	: '1-12:PM|1-12:AM'),//Default is every hour
			(fn 	? fn 	: function() { jQuery(jQuery.timeRule.settings.parent).html(jQuery.timeRule.clock()); })//Default is clock
		];
	},
	run: function (settings) {
		if (rules) {
			this.settings = settings;
		}
		
		if (this.settings.rules.length >= -1) {
			var rules;
			rules = this.settings.rules;
			
			jQuery(rules).each(function(i) {
				var day 	= rules[i][0];
				var rule 	= rules[i][1];
				var fn 		= rules[i][2];
				
				if (day) {
					jQuery.timeRule.dayRuler(day, rule, fn, true);
				} else {
					jQuery.timeRule.timeRuler(rule, fn, true);
				}
			});
		}
		
		this.temp = setTimeout('jQuery.timeRule.run()', 1000);//Lets keep it's memory controlled, no leaks
	}
};
