// UTF-8
// meltdown.js
// Copyright (c) 2007 KAZUMiX
// http://d.hatena.ne.jp/KAZUMiX/20071105/meltdown
// Licensed under the MIT License:
// http://www.opensource.org/licenses/mit-license.php

// 倉林コメント
// meltdown.js が面白い！
// bookmarklet を人のサーバに読みにいくのは嫌だ。
// FF の機能拡張 JSAction で使えるようにしてみた。
// コナミコマンドで動いたら面白いよね。
// せっかくだから滅びの言葉で発動するように。
// http://www.lifehackslite.com/
// mailto : KurabayashiHiroshi@next-group.jp
//

function meltdown(){

    // ブラウザがIEで後方互換かどうかのフラグをセット
    //var IeQuirks = false;
    //if(window.attachEvent && document.compatMode == 'BackCompat')IeQuirks = true;

    // 全要素を取得
    var all = document.body.getElementsByTagName('*');

    // ドキュメントの高さ
    // スタイルで使うときは px つける
    var documentHeight = document.body.scrollHeight;

    // 表示ウィンドウの高さ
    var windowHeight = Math.max(document.body.clientHeight, document.documentElement.clientHeight);

    // ラッパーを追加する
    var boxHeight = Math.max(documentHeight, windowHeight);
    var divBegin = '<div style="width:100%;overflow:hidden;height:' + boxHeight + 'px;">';
    var divEnd = '</div>';
    document.body.innerHTML = divBegin + document.body.innerHTML + divEnd;

    // 全要素の絶対値座標を保存する
    // offsetParentを持たない要素（scriptとか）は除外する
    // IEはこのチェックじゃだめ。実際に動いたかどうかでもチェック。
    var targetEles = [];
    var i,len;
    for(i=0,len=all.length; i<len; i++){
	if(!all[i].offsetParent)continue;
	all[i].point = getPoint(all[i]);
	targetEles[targetEles.length] = all[i];
    }

    // 要素 ele の x,y 座標を絶対値で取得する関数
    function getPoint(ele){
	var x=0,y=0;
	while(ele){
	    x += ele.offsetLeft;
	    y += ele.offsetTop;
	    ele = ele.offsetParent;
	}
	return {x:x, y:y};
    }

    // 設定するスタイルプロパティの値を準備する
    var ele;
    var eleParent;
    for(i=0,len=targetEles.length; i<len; i++){
	ele = targetEles[i];
	eleParent = ele.parentNode;
	// widthとheightを記録する
	// clientWidth がゼロなら offsetWidth
	// そうじゃなければ小さいほう
	if(ele.clientWidth == 0){
	    ele._width = ele.offsetWidth;
	}else{
	    ele._width = Math.min(ele.offsetWidth, ele.clientWidth);
	}
	if(ele.clientHeight == 0){
	    ele._height = ele.offsetHeight;
	}else{
	    ele._height = Math.min(ele.offsetHeight, ele.clientHeight);
	}

	// 親からのオフセット座標を保存する
	if(eleParent.point){
	    ele._x = ele.point.x - eleParent.point.x;
	    ele._y = ele.point.y - eleParent.point.y;
	    ele.parentX = eleParent.point.x;
	    ele.parentY = eleParent.point.y;
 	}else{
	    ele._x = ele.point.x;
	    ele._y = ele.point.y;
	}
    }

    // ターゲット要素のpositionをabsoluteにし、現在の座標をセットする
    var ele;
    for(i=0,len=targetEles.length; i<len; i++){
	ele = targetEles[i];
	// 親ノードとの差分をセットする
	//ele.style.overflow = 'visible';
	ele.style.position = 'absolute';
	ele.style.margin = '0px';
	ele.style.padding = '0px';
	ele.style.width = ele._width + 'px';
	ele.style.height = ele._height + 'px';
	//ele.style.display = 'block';
	ele.style.left = ele._x + 'px';
	ele.style.top = ele._y + 'px';
    }

    // 指定要素を画面外に落とすアニメーションクラス
    // コンストラクタ
    function Falldown(target){
	this.ele = target;
	this.speed = 1;
	this.left = target.offsetLeft;
	//this.leftRightSpeed = 2;
	this.leftRightSpeed = Math.random()*3;
    }
    // start(アニメーション開始遅延時間)
    Falldown.prototype.start = function(delay){
	this.targetY = boxHeight - this.ele.point.y;
	var scope = this;
	setTimeout(function(){scope.loop()},delay);
    }
    // loop()
    Falldown.prototype.loop = function(){
	//console.log(this.targetY,this.ele.offsetTop);
	if(this.targetY < this.ele.offsetTop)return;
	var _top = this.ele.offsetTop;
	this.ele.style.top = this.ele.offsetTop + parseInt(this.speed) + 'px';
	this.speed *= 2;
	this.left += this.leftRightSpeed;
	this.ele.style.left = parseInt(this.left) + 'px';
	var scope = this;
	// 要素の位置が変わらなかったら動かせない要素なので終わり
	if(this.ele.offsetTop==_top)return;
	// ループ
	setTimeout(function(){scope.loop()},70);
    }

    //アニメーション割り当てスタート
    //追加したdivは割り当てない
    for(i=0; i<targetEles.length-1; i++){
	var obj = new Falldown(targetEles[targetEles.length-1-i]);
	obj.start(i*30);
    }
}

// meltdown.js ここまで


////////////////////////////////////////////////////////////////////
// ここから、コナミコマンドでバルスを実行する。
//
// 以下、
// お知らせ:「コナミコマンド」を実装しました
// http://n-styles.com/main/archives/2007/07/26-033445.php
// を元に、
// JavaScript で波○拳を繰り出すことはできるか？
// http://www.rmake-labo.com/akasata/articles/show/181
// で一般化されたもの
// にバルスを埋め込んだもの。
////////////////////////////////////////////////////////////////////

//KonmaiCommand 2007.07.26作成
//著作権は主張いたしません。ご自由にお使いください。
//JavaScript部分と、外部スタイルシート呼び出し部分、Bodyタグ内のOnKeyDownがあれば動作します。
//外部スタイルシートはパワーアップ時のものを先に記述してください。
//今回はヘッダに直接JavaScriptを記述していますが、外部.jsファイルにしたほうが修正が楽になります。

//今回使用している2つのスタイルシートはほぼ同じ内容で、色と文字サイズだけを変化させています。
//スタイルシートの内容を大幅に変えれば、コマンド発動時にレイアウト自体を変化させることも可能です。

//if文ばっかりなのは、あんたたちが読みやすくなるようにしてるだけなんだからね！
//べ、べつに配列とかが分からない訳じゃないんだから！勘違いしないでよね！！
//もっとスマートな実装に改良してくれてもお礼なんていわないんだから！

//強制じゃないけど、コード流用するならリンク張ってくれたら…う、うれしいかも…
//http://n-styles.com/main/archives/2007/07/26-033445.php

function KeyCommandProcessor(keys, onSuccess, onError) {
	this.keys = keys;
	this.onSuccess = onSuccess;
	this.onError = onError;
	this.position = 0;
	
	this.process = function(key) {
		if (this.position < this.keys.length) {
			if (this.keys[this.position] == key) {
				this.position += 1;
				if (this.position == this.keys.length) {
					this.onSuccess();
					this.position = 0;
				}
			}
			else {
				this.position = 0;
				//this.onError();
			}
		}
	}
}

// 上、上、下、下、左、右、左、右、b、a
//var keys = [38,38,40,40,37,39,37,39,66,65];
// [ESC]
//var keys = [27];
// B, A, L, S, E
var keys = [66,65,76,83,69];

function onSuccess() {
	//alert('キー入力成功！');
	meltdown();
}

function onError() {
	alert('キー入力失敗！');
}

var processor = new KeyCommandProcessor(keys, onSuccess, onError);

// イベントハンドラの作成
function onKeyDown(evt) {
	// IE, Firefox 対応
	var event = evt || window.event;
	//document.getElementById('console').innerHTML += event.keyCode + ", ";
	
	// Key 処理
	processor.process(event.keyCode);
}

addEventListener('keydown',
	function(evt) {
		// IE, Firefox 対応
		var event = evt || window.event;
		// Key 処理
		processor.process(event.keyCode);
	},true);