/******************************************************************************
	tc.js	TweetClock
		$Id: tc.js,v 1.9 2009/10/21 05:50:42 kei Exp $
******************************************************************************/

if ((typeof(com) === 'undefined') || (! com)) {
	com = {};
}
if ((typeof(com.nantoka) === 'undefined') || (! com.nantoka)) {
	com.nantoka = {};
}

(function() {
com.nantoka.tweetClock = function() {
	this.posX = 240;
	this.posY = 240;

	this.radNumber24 = 130;
	this.sizeNumber24 = 24;
	this.sizeCenter = 48;
	this.radMinDot = 160;
	this.sizeMinDot = 32;
	this.sizeMinDotNum = 12;
	this.radLocalTime = 100;
	this.sizeLocalTime = 20;
	this.radLocalAmPm = 70;
	this.sizeLocalAmPm = 20;
	this.radHistgram = 175;
	this.sizeHistgram = 24;
	this.colHistgramFg = [ 255, 0, 0 ];
	this.colHistgramBg = [ 255, 248, 220 ];
	this.radTweet = 190;
	this.radTweetMax = 220;
	this.sizeTweet = 10;
	this.sizeLoading = 64;

	this.elmLoading = null;
	this.elmTweetClock = null;
	this.elmCenter = null;
	this.elmNumber24 = [];
	this.elmMinDot = [];
	this.elmTweet = [];
	this.elmHistgram = [];

	this.radHourHands = 80;
	this.sizeHourHands = 24;
	this.radMinHands = 110;
	this.sizeMinHands = 16;
	this.radSecHands = 130;
	this.sizeSecHands = 96;
	this.elmHourHands = [];
	this.elmMinHands = [];
	this.elmSecHands = [];

	this.animLocalTimeTo = 0;
	this.animLocalTimeNow = 0;
	this.animLocalTimeTimerId = null;
	this.animLocalTimeStep = 2 * Math.PI / 90;
	this.elmLocalTime = [];
	this.elmLocalAmPm = [];

	this.utcOffset = 0;
	this.moveClockHandsTimerId = null;
	this.timerGetUserTimeline = null;
	this.arrayTimeLine = [];

	this.focusLock = false;

	this.init.apply(this, arguments);
	return this;
};

com.nantoka.tweetClock.prototype = {
	// load error
	loadError: function() {
		if (this.elmLoading) {
			var e = this.elmLoading;
			e.innerHTML = 'Load Error!'
			e.style.zIndex = 2000;
			e.style.color = '#FF0000';
		}
	},

	// 文字盤の描画
	drawClockFace: function() {
		if (this.elmTweetClock) {
			var elmTweetClock = this.elmTweetClock;

			// Center dot
			var e = this.elmCenter = document.createElement('div');
			e.id = 'Center'
			e.innerHTML = '&#x25cf;';
			e.style.zIndex = 100;
			e.style.color = '#2E8B57';
			e.style.fontFamily = "'Courier New', monospace";
			e.style.fontSize = this.sizeCenter + 'px';
			e.style.width = this.sizeCenter + 'px';
			e.style.position = 'absolute';
			e.style.top = (this.posY - this.sizeCenter / 2) + 'px';
			e.style.left = (this.posX - this.sizeCenter / 2) + 'px';
			elmTweetClock.appendChild(e);

			// numbers 24
			for (var i = 0; i < 24; i++) {
				var x = this.posX + Math.cos((2 * Math.PI / 24 * i) - Math.PI / 2) * this.radNumber24;
				var y = this.posY + Math.sin((2 * Math.PI / 24 * i) - Math.PI / 2) * this.radNumber24;
				var e = this.elmNumber24[i] = document.createElement('div');
				e.id = 'Number_' + i;
				e.innerHTML = i ? i : 24;
				e.style.zIndex = 100;
				e.style.color = '#696969';
				e.style.fontSize = this.sizeNumber24 + 'px';
				e.style.width = (this.sizeNumber24 * 2) + 'px';
				e.style.fontFamily = "'Impact', sans-serif";
				e.style.position = 'absolute';
				e.style.top = (y - this.sizeNumber24 / 2) + 'px';
				e.style.left = (x - this.sizeNumber24) + 'px';
				elmTweetClock.appendChild(e);
			}

			// histgram
			for (var i = 0; i < 96; i++) {
				var x = this.posX + Math.cos((2 * Math.PI / 96 * i) - Math.PI / 2) * this.radHistgram;
				var y = this.posY + Math.sin((2 * Math.PI / 96 * i) - Math.PI / 2) * this.radHistgram;
				var e = this.elmHistgram[i] = document.createElement('div');
				e.id = 'Histgram_' + i;
				e.innerHTML = '&#x25cf;';
				e.style.zIndex = 100;
				e.style.color = 'rgb(' + this.colHistgramBg[0] + ',' + this.colHistgramBg[1] + ',' + this.colHistgramBg[2] + ')';
				e.style.fontFamily = "'Courier New', monospace";
				e.style.fontSize = this.sizeHistgram + 'px';
				e.style.width = this.sizeHistgram + 'px';
				e.style.position = 'absolute';
				e.style.top = (y - this.sizeHistgram / 2) + 'px';
				e.style.left = (x - this.sizeHistgram / 2) + 'px';
				elmTweetClock.appendChild(e);
			}

			// min dot
			for (var i = 0; i < 60; i++) {
				var x = this.posX + Math.cos((2 * Math.PI / 60 * i) - Math.PI / 2) * this.radMinDot;
				var y = this.posY + Math.sin((2 * Math.PI / 60 * i) - Math.PI / 2) * this.radMinDot;
				var e = this.elmMinDot[i] = document.createElement('div');
				e.id = 'MinDot_' + i;
				if (i % 5) {
					e.innerHTML = '&#183;';
					e.style.color = '#CCCCCC';
					e.style.fontSize = this.sizeMinDot + 'px';
					e.style.width = this.sizeMinDot + 'px';
					e.style.top = (y - this.sizeMinDot / 2) + 'px';
					e.style.left = (x - this.sizeMinDot / 2) + 'px';
				}
				else {
					e.innerHTML = (i < 10) ? '0' + i : i;
					e.style.color = '#696969';
					e.style.fontSize = this.sizeMinDotNum + 'px';
					e.style.width = (this.sizeMinDotNum * 2) + 'px';
					e.style.top = (y - this.sizeMinDotNum / 2) + 'px';
					e.style.left = (x - this.sizeMinDotNum) + 'px';
				}
				e.style.zIndex = 90;
				e.style.fontFamily = "'Courier New', monospace";
				e.style.position = 'absolute';
				elmTweetClock.appendChild(e);
			}
			
			return true;
		}
		return false;
	},

	// 時計の針を描画
	drawClockHands: function() {
		if (this.elmTweetClock) {
			var elmTweetClock = this.elmTweetClock;
			for (var i = 0; i < 3; i++) {
				var e = this.elmHourHands[i] = document.createElement('div');
				e.id = 'HourHands_' + i;
				e.innerHTML = '&#x25cf;';
				e.style.zIndex = 60;
				e.style.color = '#20B2AA';
				e.style.fontFamily = "'Courier New', monospace";
				e.style.fontSize = this.sizeHourHands + 'px';
				e.style.width = this.sizeHourHands + 'px';
				e.style.position = 'absolute';
				e.style.top = (this.posY - this.sizeHourHands / 2) + 'px';
				e.style.left = (this.posX - this.sizeHourHands / 2) + 'px';
				elmTweetClock.appendChild(e);
			}
			for (var i = 0; i < 4; i++) {
				var e = this.elmMinHands[i] = document.createElement('div');
				e.id = 'MinHands_' + i;
				e.innerHTML = '&#x25cf;';
				e.style.zIndex = 70;
				e.style.color = '#00FA9A';
				e.style.fontFamily = "'Courier New', monospace";
				e.style.fontSize = this.sizeMinHands + 'px';
				e.style.width = this.sizeMinHands + 'px';
				e.style.position = 'absolute';
				e.style.top = (this.posY - this.sizeMinHands / 2) + 'px';
				e.style.left = (this.posX - this.sizeMinHands / 2) + 'px';
				elmTweetClock.appendChild(e);
			}
			for (var i = 0; i < 1; i++) {
				var e = this.elmSecHands[i] = document.createElement('div');
				e.id = 'SecHands_' + i;
				e.innerHTML = '&#x25cf;';
				e.style.zIndex = 30;
				e.style.color = '#AADDDD';
				e.style.fontFamily = "'Courier New', monospace";
				e.style.fontSize = this.sizeSecHands + 'px';
				e.style.width = this.sizeSecHands + 'px';
				e.style.position = 'absolute';
				e.style.top = (this.posY - this.sizeSecHands / 2) + 'px';
				e.style.left = (this.posX - this.sizeSecHands / 2) + 'px';
				elmTweetClock.appendChild(e);
			}
			return true;
		}
		return false;
	},

	// 時計の針を移動
	moveClockHands: function() {
		var d = new Date();
		var ss = (d.getUTCHours() + 24) * 3600 + d.getUTCMinutes() * 60 + d.getUTCSeconds() + this.utcOffset;
		var h = (ss / 3600) % 24;
		var m = (ss / 60) % 60;
		var s = ss % 60;
		var elmHourHands = this.elmHourHands;
		var elmMinHands = this.elmMinHands;
		var elmSecHands = this.elmSecHands;
		for (var i = 0; i < elmHourHands.length; i++) {
			var r = this.radHourHands - (this.radHourHands / elmHourHands.length * i);
			var x = this.posX + Math.cos((2 * Math.PI / 24 * h) - Math.PI / 2) * r;
			var y = this.posY + Math.sin((2 * Math.PI / 24 * h) - Math.PI / 2) * r;
			elmHourHands[i].style.top = (y - this.sizeHourHands / 2) + 'px';
			elmHourHands[i].style.left = (x - this.sizeHourHands / 2) + 'px';
		}
		for (var i = 0; i < elmMinHands.length; i++) {
			var r = this.radMinHands - (this.radMinHands / elmMinHands.length * i);
			var x = this.posX + Math.cos((2 * Math.PI / 60 * m) - Math.PI / 2) * r;
			var y = this.posY + Math.sin((2 * Math.PI / 60 * m) - Math.PI / 2) * r;
			elmMinHands[i].style.top = (y - this.sizeMinHands / 2) + 'px';
			elmMinHands[i].style.left = (x - this.sizeMinHands / 2) + 'px';
		}
		for (var i = 0; i < elmSecHands.length; i++) {
			var r = this.radSecHands - (this.radSecHands / elmSecHands.length * i);
			var x = this.posX + Math.cos((2 * Math.PI / 60 * s) - Math.PI / 2) * r;
			var y = this.posY + Math.sin((2 * Math.PI / 60 * s) - Math.PI / 2) * r;
			elmSecHands[i].style.top = (y - this.sizeSecHands / 2) + 'px';
			elmSecHands[i].style.left = (x - this.sizeSecHands / 2) + 'px';
		}
		var self = this;
		this.moveClockHandsTimerId = setTimeout(function(){self.moveClockHands();}, 250);
		return true;
	},

	// ローカル時刻文字版の描画
	drawLocalTime: function() {
		if (this.elmTweetClock) {
			elmTweetClock = this.elmTweetClock;
			for (var i = 0; i < 24; i++) {
				var x = this.posX + Math.cos((2 * Math.PI / 24 * i) - Math.PI / 2) * this.radLocalTime;
				var y = this.posY + Math.sin((2 * Math.PI / 24 * i) - Math.PI / 2) * this.radLocalTime;
				var e = this.elmLocalTime[i] = document.createElement('div');
				e.id = 'LocalTime_' + i;
				e.innerHTML = (i % 12) ? (i % 12) : 12;
				e.style.zIndex = 40;
				e.style.color = (i > 11) ? '#4169E1' : '#FF1493';
				e.style.fontSize = this.sizeLocalTime + 'px';
				e.style.width = (this.sizeLocalTime * 2) + 'px';
				e.style.fontFamily = "'Impact', sans-serif";
				e.style.position = 'absolute';
				e.style.top = (y - this.sizeLocalTime / 2) + 'px';
				e.style.left = (x - this.sizeLocalTime) + 'px';
				elmTweetClock.appendChild(e);
			}
			for (var i = 0; i < 2; i++) {
				var x = this.posX + Math.cos((2 * Math.PI / 24 * (i * 12 + 6)) - Math.PI / 2) * this.radLocalAmPm;
				var y = this.posY + Math.sin((2 * Math.PI / 24 * (i * 12 + 6)) - Math.PI / 2) * this.radLocalAmPm;
				var e = this.elmLocalAmPm[i] = document.createElement('div');
				e.id = 'LocalAmPm_' + i;
				e.innerHTML = i ? 'PM' : 'AM';
				e.style.zIndex = 40;
				e.style.color = i ? '#4169E1' : '#FF1493';
				e.style.fontSize = this.sizeLocalAmPm + 'px';
				e.style.width = this.sizeLocalAmPm + 'px';
				e.style.fontFamily = "'Impact', sans-serif";
				e.style.position = 'absolute';
				e.style.top = (y - this.sizeLocalAmPm / 2) + 'px';
				e.style.left = (x - this.sizeLocalAmPm) + 'px';
				elmTweetClock.appendChild(e);
			}
			return true;
		}
		return false;
	},

	// ローカル時刻文字版の指定角度への移動
	rotateLocalTime: function(rad) {
		for (var i = 0; i < this.elmLocalTime.length; i++) {
			var x = this.posX + Math.cos((2 * Math.PI / 24 * i) - Math.PI / 2 + rad) * this.radLocalTime;
			var y = this.posY + Math.sin((2 * Math.PI / 24 * i) - Math.PI / 2 + rad) * this.radLocalTime;
			this.elmLocalTime[i].style.top = (y - this.sizeLocalTime / 2) + 'px';
			this.elmLocalTime[i].style.left = (x - this.sizeLocalTime) + 'px';
		}
		for (var i = 0; i < this.elmLocalAmPm.length; i++) {
			var x = this.posX + Math.cos((2 * Math.PI / 24 * (i * 12 + 6)) - Math.PI / 2 + rad) * this.radLocalAmPm;
			var y = this.posY + Math.sin((2 * Math.PI / 24 * (i * 12 + 6)) - Math.PI / 2 + rad) * this.radLocalAmPm;
			this.elmLocalAmPm[i].style.top = (y - this.sizeLocalAmPm / 2) + 'px';
			this.elmLocalAmPm[i].style.left = (x - this.sizeLocalAmPm) + 'px';
		}
		return true;
	},

	// ローカル時刻文字盤アニメーション
	animLocalTime: function() {
		if (this.animLocalTimeTo > this.animLocalTimeNow) {
			if (this.animLocalTimeTo - this.animLocalTimeNow > this.animLocalTimeStep) {
				this.animLocalTimeNow += this.animLocalTimeStep;
			}
			else {
				this.animLocalTimeNow = this.animLocalTimeTo;
			}
			this.rotateLocalTime(this.animLocalTimeNow);
		}
		if (this.animLocalTimeTo < this.animLocalTimeNow) {
			if (this.animLocalTimeNow - this.animLocalTimeTo > this.animLocalTimeStep) {
				this.animLocalTimeNow -= this.animLocalTimeStep;
			}
			else {
				this.animLocalTimeNow = this.animLocalTimeTo;
			}
			this.rotateLocalTime(this.animLocalTimeNow);
		}
		if (this.animLocalTimeNow == this.animLocalTimeTo) {
			clearTimeout(this.animLocalTimeTimerId);
		}
		else {
			var self = this;
			this.animLocalTimeTimerId = setTimeout(function(){self.animLocalTime();}, 25);
		}
		return true;
	},

	// user_timeline呼び出し
	getUserTimeline: function() {
		var self = this;
		var e = document.createElement("script");
		com.nantoka.tweetClock.CbGetUserTimeline = function(j) { self.cbUserTimeline(j); };
		e.setAttribute("type", "text/javascript");
		e.setAttribute("src", "http://twitter.com/statuses/user_timeline.json?callback=com.nantoka.tweetClock.CbGetUserTimeline&count=200&screen_name=" + this.userName);
		e.onerror = function(e){
			self.loadError();
		};
		this.timerGetUserTimeline = setTimeout(function() { self.loadError(); }, 20 * 1000);
		document.getElementsByTagName("head").item(0).appendChild(e);
		return true;
	},

	// histgram更新
	updateHistgram: function(arr, d) {
		var n = arr.length;
		d = (d * arr.length) / (24 * 60 * 60);
		var i = ~~(d);
		var f = d - i;
		arr[i % n] += 1 - f;
		arr[(i + 1) % n] += f;
		return;
	},

	// Tweet MouseOver イベント処理
	indexLastTweet: -1,
	evTweetOnMouseOver: function(i) {
		if (this.focusLock) {
			return true;
		}
		if (this.indexLastTweet != -1) {
			var e = this.elmTweet[this.indexLastTweet];
			e.innerHTML = '&#x2605;';	// ★
			e.style.color = e.color;
			e.style.zIndex = e.zIndex;
			e.style.fontSize = this.sizeTweet + 'px';
			e.style.width = this.sizeTweet + 'px';
			e.style.top = (e.pos_y - this.sizeTweet / 2) + 'px';
			e.style.left = (e.pos_x - this.sizeTweet / 2) + 'px';
		}
		var e = this.elmTweet[i];
		e.innerHTML = '&#x2606;';	// ☆
		e.style.color = e.colorFocus;
		e.style.fontSize = (this.sizeTweet * 2) + 'px';
		e.style.width = (this.sizeTweet * 2) + 'px';
		e.style.top = (e.pos_y - this.sizeTweet) + 'px';
		e.style.left = (e.pos_x - this.sizeTweet) + 'px';
		var e = document.getElementById('TweetBox');
		if (e) {
			var status = this.arrayTimeLine[i].text.replace(/((https?|s?ftp|ssh)\:\/\/[^"\s\<\>]*[^.,;'">\:\s\<\>\)\]\!])/g,
				function(url) {
					return '<a href="'+url+'">'+url+'</a>';}).replace(/\B@([_a-z0-9]+)/ig,
						function(reply) {
							return reply.charAt(0)+'<a href="http://twitter.com/'+reply.substring(1)+'">'+reply.substring(1)+'</a>';});
			e.innerHTML = status;
		}

		var d = document.getElementById('TweetDateTime');
		if (d) {
			var dt = new Date();
			var arr = this.arrayTimeLine[i].created_at.split(" ");
			var ep = Date.parse(arr[1] + " " + arr[2] + ", " + arr[5] + " " + arr[3]);
			dt.setTime(ep + this.utcOffset * 1000);
			d.innerHTML = '<a href="http://twitter.com/' + this.userName + '/status/' + this.arrayTimeLine[i].id
				+ '" target="_blank">' + this.dateToText(dt) + '</a> '
				+ this.arrayTimeLine[i].user.time_zone
				+ ' by ' + this.arrayTimeLine[i].source;
		}
		var self = this;
		var e = document.getElementById('TweetNext');
		if (i) {
			e.style.backgroundColor = '#3082af';
			e.style.color = '#ccffff';
			e.onclick = (function(j){return function(){self.OnTweetClick(j);return false;}})(i-1);
		}
		else {
			e.style.backgroundColor = '#ccffff';
			e.style.color = '#3082af';
			e.onclick = null;
		}
		var e = document.getElementById('TweetPrev');
		if (i < (this.arrayTimeLine.length - 1)) {
			e.style.backgroundColor = '#3082af';
			e.style.color = '#ccffff';
			e.onclick = (function(j){return function(){self.OnTweetClick(j);return false;}})(i+1);
		}
		else {
			e.style.backgroundColor = '#ccffff';
			e.style.color = '#3082af';
			e.onclick = null;
		}

		this.indexLastTweet = i;
		return true;
	},

	// Tweet MouseOut イベント処理
	evTweetOnMouseOut: function(i) {
		return true;
	},

	// Tweet OnClick イベント処理
	evTweetOnClick: function(i) {
		if (i != this.indexLastTweet) {
			this.focusLock = false;
			this.evTweetOnMouseOver(i);
		}
		var e = this.elmTweet[this.indexLastTweet];
		if (this.focusLock) {
			e.innerHTML = '&#x2606;';	// ☆
			e.style.zIndex = e.zIndex;
			this.focusLock = false;
		}
		else {
			e.innerHTML = '&#x2605;';	// ★
			e.style.zIndex = 1000;
			this.focusLock = true;
		}
		return true;
	},

	// user_timeline 出力
	colTweetFg : [
			[ 255, 140, 0 ],	// darkorange
			[ 255, 0, 0 ],		// red
			[ 0, 100, 0 ],		// darkgreen
			[ 0, 0, 139 ],		// darkblue
			[ 255, 20, 147 ]	// deeppink
	],
	colTweetBg : [
		[ 255, 250, 205 ],		// lemonchiffon
		[ 255, 160, 122 ],		// light salmon
		[ 144, 238, 144 ],		// lightgreen
		[ 173, 216, 230 ],		// lightblue
		[ 255, 182, 193 ]		// lightpink
	],
//	colTweetFg: [ 255, 140, 0 ],
//	colTweetBg: [ 240, 230, 140 ],
	colTweetFocus: [ 255, 0, 0 ],
	dispUserTimeLine: function() {
		if (! this.elmTweetClock) {
			return false;
		}
		if (this.arrayTimeLine.length) {
			var arrayTimeLine = this.arrayTimeLine;
			var now = new Date();
			var rgb = [];
			var hgram = new Array(this.elmHistgram.length);
			for (var i = 0; i < hgram.length; i++) {
				hgram[i] = 0.0;
			}
			var arr = arrayTimeLine[0].created_at.split(" ");
			var ep_last = Date.parse(arr[1] + " " + arr[2] + ", " + arr[5] + " " + arr[3]) / 1000 - now.getTimezoneOffset() * 60;
			var ep_div = 1.0;
			if (arrayTimeLine.length > 1) {
				var arr = arrayTimeLine[arrayTimeLine.length-1].created_at.split(" ");
				var ep_start = Date.parse(arr[1] + " " + arr[2] + ", " + arr[5] + " " + arr[3]) / 1000 - now.getTimezoneOffset() * 60;
				ep_div = ep_last - ep_start
			}
			var hashCol = {};
			var indexCol = 0;
			for (var i = 0; i < arrayTimeLine.length; i++) {
				var arr = arrayTimeLine[i].created_at.split(" ");
				var ep = Date.parse(arr[1] + " " + arr[2] + ", " + arr[5] + " " + arr[3]) / 1000 - now.getTimezoneOffset() * 60;
				var df = now.getTime() / 1000 - ep;
				var r = this.radTweet + (this.radTweetMax - this.radTweet) * (ep_last - ep) / ep_div;
				var d = (ep + this.utcOffset) % (24 * 60 * 60);
				var x = this.posX + Math.cos((2 * Math.PI / (24 * 60 * 60) * d) - Math.PI / 2) * r;
				var y = this.posY + Math.sin((2 * Math.PI / (24 * 60 * 60) * d) - Math.PI / 2) * r;
				var e = this.elmTweet[i] = document.createElement('div');
				e.id = 'Tweet_' + i;
				e.innerHTML = '&#x2605;';
				e.style.zIndex = 1000 - i;

				var src = arrayTimeLine[i].source;
				var col = 0;
				if (typeof(hashCol[src]) == 'undefined') {
					hashCol[src] = indexCol++;
				}
				var colno = hashCol[src] % this.colTweetFg.length;
				var colfg = this.colTweetFg[colno]
				var colbg = this.colTweetBg[colno]
				for (j = 0; j < 3; j++) {
					rgb[j] = colfg[j] + (colbg[j] - colfg[j]) * (ep_last - ep) / ep_div;
				}
				e.style.color = 'rgb(' + ~~(rgb[0]) + ',' + ~~(rgb[1]) + ',' + ~~(rgb[2]) + ')';
				e.style.fontFamily = "'Courier New', monospace";
				e.style.fontSize = this.sizeTweet + 'px';
				e.style.position = 'absolute';
				e.style.top = (y - this.sizeTweet / 2) + 'px';
				e.style.left = (x - this.sizeTweet / 2) + 'px';
				e.color = 'rgb(' + ~~(rgb[0]) + ',' + ~~(rgb[1]) + ',' + ~~(rgb[2]) + ')';
				e.colorFocus = 'rgb(' + colfg[0] + ',' + colfg[1] + ',' + colfg[2] + ')';
				e.pos_x = x;
				e.pos_y = y;
				e.zIndex = 1000 - i;
				var self = this;
				e.onmouseover = (function(j){return function(){self.OnTweetMouseOver(j);}})(i);
				e.onmouseout = (function(j){return function(){self.OnTweetMouseOut(j);}})(i);
				e.onclick = (function(j){return function(){self.OnTweetClick(j);}})(i);
				this.elmTweetClock.appendChild(e);
				this.updateHistgram(hgram, d);
			}
			var hmax = 0.0;
			for (var i = 0; i < hgram.length; i++) {
				if (hgram[i] > hmax) {
					hmax = hgram[i];
				}
			}
			if (hmax) {
				for (var i = 0; i < hgram.length; i++) {
					for (j = 0; j < 3; j++) {
						rgb[j] = this.colHistgramBg[j] + (this.colHistgramFg[j] - this.colHistgramBg[j]) * hgram[i] / hmax;
					}
					this.elmHistgram[i].style.color = 'rgb(' + ~~(rgb[0]) + ',' + ~~(rgb[1]) + ',' + ~~(rgb[2]) + ')';
				}
			}
			this.evTweetOnMouseOver(0);
		}
		if (this.elmLoading) {
			this.elmTweetClock.removeChild(this.elmLoading);
			this.elmLoading = null;
		}
		return true;
	},

	// 時計表示の On/Off
	displayClock: function(visible) {
		var e = document.getElementById('ClockFrame');
		if (e) {
			if (visible) {
				e.style.display = 'block';
			}
			else {
				e.style.display = 'none';
			}
		}
		return true;
	},

	// user_timeline callback処理
	cbUserTimeline: function(json) {
		if (this.timerGetUserTimeline) {
			clearTimeout(this.timerGetUserTimeline);
			this.timerGetUserTimeline = null;
		}
		if (json.error) {
			this.loadError();
			return false;
		}
		this.utcOffset = json[0].user.utc_offset;
		var e = document.getElementById('LocalTimeZone');
		if ((e) && (e.options[0])) {
			e.options[0].text = json[0].user.time_zone;
		}
		this.moveClockHands();
		this.arrayTimeLine = json;
		this.dispUserTimeLine();
		return true;
	},

	// 時刻文字列生成
	dateToText: function(d) {
		if (d) {
			var str;
			str  = d.getFullYear() + '-';
			str += (((d.getMonth() + 1) < 10) ? '0' + (d.getMonth() + 1) : (d.getMonth() + 1)) + '-';
			str += ((d.getDate() < 10) ? '0' + d.getDate() : d.getDate()) + ' ';
			str += ((d.getHours() < 10) ? '0' + d.getHours() : d.getHours()) + ':';
			str += ((d.getMinutes() < 10) ? '0' + d.getMinutes() : d.getMinutes()) + ':';
			str += ((d.getSeconds() < 10) ? '0' + d.getSeconds() : d.getSeconds());
			return str;
		}
		return;
	},

	start: function() {
		this.elmTweetClock = document.getElementById('TweetClock');
		if (this.elmTweetClock) {
			var etc = this.elmTweetClock;
			this.displayClock(true);
			if (this.userName) {
				this.getUserTimeline();

				etc.style.textAlign = 'center';
				etc.style.cursor = 'default';

				elmLoading = this.elmLoading = document.createElement('div');
				elmLoading.id = 'Loading';
				elmLoading.innerHTML = 'Now Loading...'
				elmLoading.style.zIndex = 2000;
				elmLoading.style.color = '#FFA500';
				elmLoading.style.fontSize = this.sizeLoading + 'px';
				elmLoading.style.width = '400px';
				elmLoading.style.fontFamily = "'Impact', sans-serif";
				elmLoading.style.position = 'absolute';
				elmLoading.style.top = (this.posY - this.sizeLoading / 2) + 'px';
				elmLoading.style.left = (this.posX - 200) + 'px';
				etc.appendChild(elmLoading);

				this.drawClockFace();
				this.drawLocalTime();
				this.drawClockHands();
			}
			else {
				this.displayClock(false);
			}
		}
		return true;
	},

	finish: function() {
		if (this.moveClockHandsTimerId) {
			clearTimeout(this.moveClockHandsTimerId);
		}
		this.moveClockHandsTimerId　= null;
		if (this.animLocalTimeTimerId) {
			clearTimeout(this.animLocalTimeTimerId);
		}
		this.animLocalTimeTimerId = null;
		if (this.timerGetShowUser) {
			clearTimeout(this.timerGetShowUser);
		}
		this.timerGetShowUser = null;
	},

	setLocalTime: function(offset) {
		if (offset == '') {
			this.animLocalTimeTo = 0;
		}
		else {
			this.animLocalTimeTo = - 2 * Math.PI / 24 * (offset - this.utcOffset / 3600);
		}
		if (this.animLocalTimeTimerId) {
			clearTimeout(this.animLocalTimeTimerId);
		}
		this.animLocalTime();
		return true;
	},

	// ローカル時刻表示の文字盤を回転
	SetLocalTime: function (offset) {
		return this.setLocalTime(offset);
	},

	OnTweetMouseOver: function(i) {
		this.evTweetOnMouseOver(i);
	},

	OnTweetMouseOut: function(i) {
		this.evTweetOnMouseOut(i);
	},

	OnTweetClick: function(i) {
		this.evTweetOnClick(i);
	},

	GetUserName: function() {
		return this.userName;
	},

	OnSubmitUser: function() {
		var e = document.getElementById('InputUserName');
		if ((e) && (e.value)) {
			location.href = 'http://tc.nantoka.com/' + e.value;
		}
		return true;
	},

	init: function(name) {
		name.replace(/[a-zA-Z0-9_]+/, "$1");
		this.userName = name;

		var self = this;
		if (window.addEventListener) {
			window.addEventListener('load', function(){self.start();}, false);
		}
		else {
			attachEvent('onload', function(){self.start();});
		};

		if (window.addEventListener) {
			window.addEventListener('unload', function(){self.finish();}, false);
		}
		else {
			attachEvent('onunload', function(){self.finish();});
		};
	}
};

})();

