
if (!Function.prototype.bind)
	Function.prototype.bind = function(object) {
	  	var __method = this;
	  	return function() { return __method.apply(object); }
	}
if (!Function.prototype.bindAsEventListener)
	Function.prototype.bindAsEventListener = function(object) {
	  	var __method = this;
	  	return function(event) { return __method.call(object, (event || window.event)); }
	}


var sasurai = {
	interval: 150,

	chars: new Array(64),
	mx: -100,
	my: -100,

	init: function() {
		this.html = '<img src="' + sasurai.basePath + 'images/sasurai_house_body.gif" onclick="return sasurai.onClick(this)" alt="飛ぶかもしれません" title="飛ぶかもしれません" style="cursor:pointer; margin-bottom:0" /><br /><a href="http://interpot.nifty.com/" alt="タネまき・水やり・InterPot（インターポット）ホームページはクリック！" title="タネまき・水やり・InterPot（インターポット）ホームページはクリック！" target="_top"><img src="' + sasurai.basePath + 'images/sasurai_house_bottom.gif" border="0" /></a>';
		this.preload(this.createSasurai().images);
		this.gecko = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
		this.opera = !!window.opera;
		this.safari = navigator.userAgent.indexOf("safari") != -1;

		this.mouseMove = this.mouseMove.bindAsEventListener(this);
		this.timeout = this.timeout.bind(this);

		sasurai.observe(document, "mousemove", sasurai.mouseMove);

		this.charsDiv.innerHTML = this.html;

		//this.insertChar(createBox(450, 500));
		sasurai.timeout();
	},


	CharBase: {
			id: 0,
			state: 0,
			x: 0,
			y: 0,
			dx: 0,
			dy: 0,
			images: 0,
			imageIndex: 0,
			elem: 0,

			baseinit: function(id) {
				this.id = id;
				this.elem = document.getElementById("char__" + id);
				if (!this.elem) {
					this.elem = document.createElement("img");
					this.elem.setAttribute("id", "char__" + id);
					sasurai.observe(this.elem, "mousedown", function(e) { sasurai.cancelEvent(e); return sasurai.onClickChar(id); });
					this.elem.style.position = "absolute";
					this.elem.style.visibility = "hidden";
					//this.elem.style.border = "1px dotted #000000";
					sasurai.charsDiv.appendChild(this.elem);
				}
				//if (this.onClick) this.elem.style.cursor = "pointer";
				if (this.onClick) {
					if (sasurai.gecko) this.elem.style.cursor = "-moz-grab";
					else this.elem.style.cursor = "move";
				} else this.elem.style.cursor = null;
				this.init();
				this.elem.src = sasurai.basePath + this.images[this.imageIndex];
				this.setPos(this.x, this.y);
				this.elem.style.visibility = "visible";
			},

			init: function() {
				// for override
			},

			frame: function() {
				if (this.move()) {
					return true;
				}
				this.changeImage();
				this.setPos(this.x, this.y);
				return false;
			},

			move: function() {
				return false;
				// for override
			},

			changeImage: function() {
				if (this.images.length > 0) {
					this.imageIndex = (this.imageIndex + 1) % this.images.length;
					this.elem.src = sasurai.basePath + this.images[this.imageIndex];
				}
			},

			// x 軸のみチェック。y軸はドキュメント先頭より上の場合は true。
			isOverflow: function() {
				if (this.x < -this.elem.offsetWidth
				 || this.x > this.right() + this.elem.offsetWidth
				 || this.y < -this.elem.offsetHeight) {
					return true;
				}
				return false;
			},
			bottom: function() {
				return sasurai.scrollY() + sasurai.screenHeight() - this.elem.offsetHeight - 1;
			},
			right: function() {
				return sasurai.scrollX() + sasurai.screenWidth() - this.elem.offsetWidth - 1;
			},
			isTouch: function() {
				if (this.x > sasurai.mx || this.x + elem.offsetWidth < sasurai.mx
				 || this.y > sasurai.my || this.y + elem.offsetHeight < sasurai.my) return false;
				return true;
			},
			isDragging: function() {
				return sasurai.dragChar && sasurai.dragChar == this;
			},
			hide: function() {
				this.elem.style.visibility = "hidden";
				this.x = 0;
				this.y = 0;
				this.setPos(this.x, this.y);
			},
			setZIndex: function(i) {
				this.zIndex = i;
			},
			setPos: function(x, y) {
				this.x = x;
				this.y = y;
				sasurai.setPos(this.elem, x, y);
			}
	},


	timeout: function() {
		for (var i = 0; i < this.chars.length; i++) {
			if (!this.chars[i]) continue;
			if (this.chars[i].frame()) {
				this.chars[i].hide();
				this.chars[i] = null;
			}
		}
		setTimeout(this.timeout, this.interval);
	},

	onClick: function(e) {
		var pos = sasurai.getXY(e);
		//*
		this.insertChar(this.createSasurai(pos.x + e.offsetWidth / 2 - 4, pos.y + 60));
		/*/
		var v = Math.random();
		if (v < 0.25) {
			this.insertChar(this.createSasurai(e.offsetLeft + e.offsetWidth / 2 - 16, e.offsetTop));
		} else if (v < 0.5) {
			this.insertChar(this.createPapiro(e.offsetLeft + e.offsetWidth / 2 - 16, e.offsetTop));
		} else if (v < 0.75) {
			this.insertChar(this.createDonDon(e.offsetLeft + e.offsetWidth / 2 - 16, e.offsetTop));
		} else {
			this.insertChar(this.createUni(e.offsetLeft + e.offsetWidth / 2 - 16, e.offsetTop));
		}
		//*/
		return false;
	},

	insertChar: function(o) {
		for (var i = 0; i < this.chars.length; i++) {
			if (!this.chars[i]) {
				this.chars[i] = o;
				o.baseinit(i);
				return;
			}
		}
	},

	onClickChar: function(id) {
		if (this.chars[id] && this.chars[id].onClick) this.chars[id].onClick();
		return false;
	},

	setPos: function(e, x, y) {
		if (!e) return;
		if (e.left) {
			e.left = x;
			e.top = y;
		} else {
			e.style.left = x + "px";
			e.style.top = y + "px";
		}
	},

	screenWidth: function() {
		if (document.all)
			if (document.documentElement.clientWidth > 0)
				return document.documentElement.clientWidth;
			else return document.documentElement.scrollWidth;
		return window.innerWidth;
	},
	screenHeight: function() {
		if (document.all)
			if (document.documentElement.clientHeight > 0)
				return document.documentElement.clientHeight;
			else return document.documentElement.scrollHeight;
		return window.innerHeight;
	},

	scrollX: function() {
		return document.body.scrollLeft || document.documentElement.scrollLeft;
	},
	scrollY: function() {
		return document.body.scrollTop || document.documentElement.scrollTop;
	},

	getXY: function(e) {
		// thanx > http://developer.yahoo.com/yui/docs/dom/index.html/overview-summary-Dom.js.html
		if (e.parentNode === null || e.style.display == 'none') return null;

		var parent = null;
		var pos = new Object();
		var box;

		if (e.getBoundingClientRect) { // IE
			box = e.getBoundingClientRect();
			var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
			var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);

			pos.x = box.left + scrollLeft - 2;
			pos.y = box.top + scrollTop - 2;
			return pos;
		} else if (document.getBoxObjectFor) { // gecko
			box = document.getBoxObjectFor(e);
			pos.x = box.x;
			pos.y = box.y;
			if (!isNaN(parseInt(e.style.borderLeftWidth)))
				pos.x -= parseInt(e.style.borderLeftWidth);
			if (!isNaN(parseInt(e.style.borderTopWidth)))
				pos.y -= parseInt(e.style.borderTopWidth);
		} else { // safari & opera
			pos.x = e.offsetLeft;
			pos.y = e.offsetTop;
			parent = e.offsetParent;
			if (parent != e) {
				while (parent) {
				 	pos.x += parent.offsetLeft;
				 	pos.y += parent.offsetTop;
				 	parent = parent.offsetParent;
				}
			}
			if (sasurai.opera || (sasurai.safari && e.style.position == 'absolute')) {
				pos.x -= document.body.offsetLeft;
				pos.y -= document.body.offsetTop;
			}
		}

		if (e.parentNode) parent = e.parentNode;
		else parent = null;

		while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') {
			// account for any scrolled ancestors
			pos.x -= parent.scrollLeft;
			pos.y -= parent.scrollTop;

			if (parent.parentNode) parent = parent.parentNode;
			else parent = null;
		}
		return pos;
	},

	mouseMove: function(event) {
		this.mx = event.pageX || (event.clientX +
	  		(document.documentElement.scrollLeft || document.body.scrollLeft));
	  	this.my = event.pageY || (event.clientY +
	  		(document.documentElement.scrollTop || document.body.scrollTop));

		if (!this.dragChar) return;
		this.dragChar.setPos(this.mx + this.dragOffsetX, this.my + this.dragOffsetY);
	},

	/*
	createBox: function(x, y) {
		var o = this.extend({
			init: function() {
				this.images = new Array("box.gif");
			},
			move: function() {
				return false;
			},
			onClick: function() {
				insertChar(createSasurai(x + 48, y + 12));
			}
		}, this.CharBase);
		o.x = x;
		o.y = y;
		return o;
	},
	*/

	createSasurai: function(x, y) {
		return sasurai.extend({
			images: new Array("images/sasurai_0.gif", "images/sasurai_1.gif", "images/sasurai_2.gif", "images/sasurai_3.gif", "images/sasurai_4.gif", "images/sasurai_3.gif", "images/sasurai_2.gif", "images/sasurai_1.gif"),
			x: x,
			y: y,
			init: function() {
				this.drop = Math.random() < 0.05;
				if (this.drop) this.elem.style.cursor = "";
				//*
				this.dx = Math.random() * 2 + 1;
				if (Math.random() < 0.5) this.dx = -this.dx;
				this.dy = Math.random() * 3 - 2;
				if (this.dx < 0) this.elem.style.filter = "FlipH()";
				else this.elem.style.filter = "";
				/*/
				this.dx = Math.random() * 5 - 2.5;
				//this.dx = Math.random() * 2 + 1;
				//if (Math.random() < 0.5) this.dx = -this.dx;
				//this.dy = Math.random() * 3 - 2;
				this.dy = -4;
				if (this.dx < 0) this.elem.style.filter = "FlipH()";
				else this.elem.style.filter = "";
				//*/
			},
			onClick: function() {
				if (this.drop) {
					this.state = 1;
					return;
				}
				this._listener = function() {
					sasurai.dragChar = null;
					if (sasurai.gecko) this.elem.style.cursor = "-moz-grab";
					sasurai.stopObserving(document, "mouseup", this._listener);
				}.bind(this);
				sasurai.observe(document, "mouseup", this._listener);
				sasurai.dragChar = this;
				sasurai.dragOffsetX = this.x - sasurai.mx;
				sasurai.dragOffsetY = this.y - sasurai.my;
				if (sasurai.gecko) this.elem.style.cursor = "-moz-grabbing";
				//this.y -= 10;
				this.setPos(this.x, this.y);
			},
			move: function() {
				if (this.isDragging()) return false;
				switch (this.state) {
					case 0:
						//*
						this.x = this.x + this.dx + (Math.random() * 5 - 2.5);
						this.y = this.y + this.dy + (Math.random() * 2 - 1);
						if (this.x > this.right() - 24) {
							this.x = this.right() - 24;
							this.dx = -this.dx;
							this.elem.style.filter = "FlipH()";
						}
						/*/
						this.x = this.x + this.dx + (Math.random() * 4 - 2);
						this.y = this.y + this.dy + (Math.random() * 2 - 1);
						if (this.x > this.right() - 24) {
							this.x = this.right() - 24;
							this.dx = -Math.abs(this.dx);
							this.elem.style.filter = "FlipH()";
						}
						if (this.dy < 2.5) this.dy += 0.1;
						if (this.y > this.bottom() + this.elem.offsetHeight) return true;
						//*/
						if (this.isOverflow()) return true;
						break;
					/*
					case 1:
						this.x = this.x + (sasurai.mx-this.x-this.elem.offsetWidth/2)/20;
						this.y = this.y + (sasurai.my-this.y-this.elem.offsetHeight/2)/20;
						break;
					*/
					case 1:
						this.x = this.x + this.dx;
						this.y = this.y + this.dy;
						this.dy -= 1;
						if (this.isOverflow()) return true;
				}
				return false;
			}
		}, this.CharBase);
	},

	/////////////////////////////////////////////////////
	observe: function(e, name, f, capture) {
		capture = capture ? capture : false;
		if (e.addEventListener) {
		  	e.addEventListener(name, f, capture);
		} else if (e.attachEvent) {
		  	e.attachEvent('on' + name, f);
		}
	},
	stopObserving: function(e, name, f, capture) {
		capture = capture ? capture : false;
		if (e.removeEventListener) {
	  		e.removeEventListener(name, f, capture);
		} else if (e.detachEvent) {
	  		try {
				e.detachEvent('on' + name, f);
	  		} catch (ex) {}
		}
	},
	cancelEvent: function(event) {
		if (event.preventDefault) {
		  	event.preventDefault();
		  	event.stopPropagation();
		} else {
		  	event.returnValue = false;
		  	event.cancelBubble = true;
		}
	},
	extend: function(destination, source) {
		for (var property in source) {
			if (!destination[property])
				destination[property] = source[property];
		}
		return destination;
	},
	preload: function(urls) {
		var img;
		for (var i = 0; i < urls.length; i++) {
			img = new Image();
			img.src = this.basePath + urls[i];
		}
	}
};

/*
sasurai.scriptEL = document.documentElement;
while (sasurai.scriptEL.tagName.toLowerCase() != "script") sasurai.scriptEL = sasurai.scriptEL.lastChild;

sasurai.basePath = sasurai.scriptEL.src.substring(0, sasurai.scriptEL.src.lastIndexOf('/') + 1);
sasurai.charsDiv = document.createElement('div');
sasurai.charsDiv.className = 'sasuraifly';
sasurai.scriptEL.parentNode.appendChild(sasurai.charsDiv);
sasurai.scriptEL = null;
/*/
sasurai.basePath = "http://interpot.nifty.com/js/";
document.write('<div id="sasuraifly_box" class="sasuraifly"></div>');
sasurai.charsDiv = document.getElementById('sasuraifly_box');
//*/

sasurai.observe(window, "load", sasurai.init.bind(sasurai));
