/**
 * 聖剣風のメニューを表示するクラス
 * @constructor
 */
function RingMenu(){
    /** メニューの数 */
    this.menuNum = 0;
    
    /** メニューの中心座標X */
    this.posX = 0;
    
    /** メニューの中心座標Y */
    this.posY = 0;
    
    /** メニューが表示中か否か */
    this.visible = false;
    
    /** リンク先のURL */
    this.url = new Array(20);
    
    /** メニューに表示するアイコン画像 */
    this.image = new Array(20);

    /** メニューに表示する枠の画像 */
    this.frameImage = '';
    
    /** 画像の位置（角度） */
    this.angle = new Array(20);
    
    /** フェードイン・アウトの表示間隔（ミリ秒） */
    this.feedInterval = 20;
    
    /** フェードイン・アウトのアニメーションの現在の回数 */
    this.feedCount = 0;
    
    /** フェードイン・アウトのアニメーションの回数 */
    this.maxTimerCount = 20;
    
    /** フェードイン・アウトするまでに移動する角度 */
    this.feedAngle = 180;
    
    /** フェードインのsetInterval実行時のId */
    this.feedInId = '';
    
    /** フェードアウトのsetInterval実行時のId */
    this.feedOutId = '';
    
    /** メニュー回転のsetInterval実行時のId */
    this.roleId = '';
	
    /** ページ移動のsetInterval実行時のId */
	this.movePageId = '';
    
    /** メニュー回転のアニメーションの現在の回数 */
    this.roleCount = 0;
    
    /** メニュー回転のアニメーションの回数 */
    this.maxRoleCount = 5;
    
    /** メニューの半径（アニメーション終了時） */
    this.minRadius = 100;
    
    /** メニューの半径（アニメーション開始時） */
    this.maxRadius = 500;
    
    /** 選択中の画像のId */
    this.selectedId = 0;
    
    /** メニュー点滅のアニメーションの現在の回数 */
    this.blinkCount = 0;
    
    /** メニュー点滅のアニメーションの回数 */
    this.maxBlinkCount = 5;
    
    /** 画像用のIdのプリフィックス */
    this.idPrefixName = "imgRingMenu";
    
    /** 枠の画像用のIdのポストフィックス */
    this.framePostfixName = new Array("TL","TR","BL","BR");

    /** メニューの画像を追加する */
    this.addMenu =  function(imageUrl,linkUrl){
        this.image[this.menuNum] = new Image();
        this.image[this.menuNum].src = imageUrl;
        this.url[this.menuNum] = linkUrl;
        this.menuNum ++;
    }

    /** 枠の画像を設定する */
    this.setFrameImage =  function(imageUrl){
        this.frameImage = new Image();
        this.frameImage.src = imageUrl;
    }
    
    /** リングメニューを初期化する */
    this.init = function(){
        //クリックイベントの追加
        Event.observe(document, "mousedown",this.clickEvent.bind(this), false);
        //クリックイベントの追加
        Event.observe(document, "contextmenu",this.contextMenuEvent.bind(this), false);
        //ダブルクリックイベントの追加
        Event.observe(document, "dblclick",this.dblClickEvent.bind(this), false);
        //マウスムーブイベント追加
        Event.observe(document, "mousemove", this.mouseMoveEvent.bind(this), false);
        //キーイベント追加
        if(Prototype.Browser.Opera){
            document.addEventListener("keypress",this.keyPressEvent.bind(this),false);
        }
        else{
            Event.observe(document, "keydown", this.keyPressEvent.bind(this), false);
        }
        //ホイールマウスのイベント追加
        Event.observe(document, "mousewheel", this.mouseWheelEvent.bind(this), false);
        Event.observe(document, "DOMMouseScroll", this.mouseWheelEvent.bind(this), false);//FireFox用
        //
        for(var i = 0; i < this.menuNum; i ++){
            this.angle[i] = 90 - i*360/this.menuNum;
            var imageObj = document.createElement("img");
            imageObj.setAttribute("src",this.image[i].src);
            imageObj.setAttribute("id",this.idPrefixName + i);
            imageObj.style.position = 'absolute';
            imageObj.style.top = -1000;
            imageObj.style.left = -1000;
            //imageObj.style.filter = "chroma(color=#ffffff)";//IE以外では動かない
            document.body.appendChild(imageObj);
        }
        //枠の追加
        if(this.frameImage != ''){
            var w = this.frameImage.width;
            var l = this.frameImage.height;
            for(var i = 0; i < 4; i ++){
                var imageObjFrame = document.createElement("img");
                imageObjFrame.setAttribute("src",this.frameImage.src);
                imageObjFrame.setAttribute("id",this.idPrefixName + this.framePostfixName[i]);
                //this.framePostfixName = new Array("TL","TR","BL","BR");
                //各4隅のみ表示
                if(i == 0){
                    imageObjFrame.style.clip = "rect(0," + w/2 + "," + l/2 + ",0)";//上、右、下、左の順番。
                }
                else if(i == 1){
                    imageObjFrame.style.clip = "rect(0," + w + "," + l/2 + "," + (w/2 + 1) + ")";
                }
                else if(i == 2){
                    imageObjFrame.style.clip = "rect(" + (l/2 + 1) + "," + w/2 + "," + l + ",0)";
                }
                else if(i == 3){
                    imageObjFrame.style.clip = "rect(" + (l/2 + 1) + "," + w + "," + l + "," + (w/2 + 1) + ")";
                }
                imageObjFrame.style.position = 'absolute';
                imageObjFrame.style.top  = -1000;
                imageObjFrame.style.left = -1000;
                document.body.appendChild(imageObjFrame);
            }
        }
    }
    
    /**
     * フェードインを開始する
     */
    this.startFeedIn = function(){
        this.feedCount = 0;
        this.feedInId = setInterval((function(){this.feedIn()}).bind(this),this.feedInterval);
    }

    /**
     * メニューをフェードインする
     */
    this.feedIn = function(){
        //実行回数をインクリメント
        this.feedCount = this.feedCount + 1;
        //
        var length = (this.maxRadius - this.minRadius)*(this.maxTimerCount - this.feedCount)/this.maxTimerCount;//長さ
        var angle = this.feedAngle*(this.maxTimerCount - this.feedCount)/this.maxTimerCount;//角度
        
        for(var j = 0; j < this.menuNum; j ++){
            //var angleIndex = (this.selectedId + j)%this.menuNum;//アイコンの角度
            var angleIndex = (j - this.selectedId + this.menuNum)%this.menuNum;//アイコンの角度
            document.getElementById(this.idPrefixName + j).style.left = this.posX - this.image[j].width/2  + (this.minRadius + length)*Math.cos((this.angle[angleIndex] + angle)/180*Math.PI);
            document.getElementById(this.idPrefixName + j).style.top  = this.posY - this.image[j].height/2 - (this.minRadius + length)*Math.sin((this.angle[angleIndex] + angle)/180*Math.PI);
        }
        //規定の回数に達したら停止
        if(this.feedCount >= this.maxTimerCount){
            clearInterval(this.feedInId);
            this.feedInId = '';
            this.frameShow();
            this.visible = true;
        }
    }

    /**
     * メニューをフェードアウトする
     */
    this.startFeedOut = function(){
        clearInterval(this.feedInId);
        this.feedInId = '';
        this.feedCount = 0;
        this.feedOutId = setInterval((function(){this.feedOut()}).bind(this),this.feedInterval);
    }
    /**
     * メニューをフェードアウトする
     */
    this.feedOut = function(){
        if(this.frameImage != ''){
            for(var i = 0; i < 4; i ++){
                document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.left = -1000;
                document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.top  = -1000;
            }
        }
        
        
        //実行回数をインクリメント
        this.feedCount = this.feedCount + 1;
        //
        var length = (this.maxRadius - this.minRadius)*this.feedCount/this.maxTimerCount;//長さ
        var angle = this.feedAngle*this.feedCount/this.maxTimerCount;//角度
        
        for(var j = 0; j < this.menuNum; j ++){
            //var angleIndex = (this.selectedId + j)%this.menuNum;//アイコンの角度
            var angleIndex = (j - this.selectedId + this.menuNum)%this.menuNum;//アイコンの角度
            document.getElementById(this.idPrefixName + j).style.left = this.posX - this.image[j].width/2  + (this.minRadius + length)*Math.cos((this.angle[angleIndex] + angle)/180*Math.PI);
            document.getElementById(this.idPrefixName + j).style.top  = this.posY - this.image[j].height/2 - (this.minRadius + length)*Math.sin((this.angle[angleIndex] + angle)/180*Math.PI);
        }
        //規定の回数に達したら停止
        if(this.feedCount >= this.maxTimerCount){
            clearInterval(this.feedOutId);
            this.feedOutId = '';
            //座標をマイナスにして画面から隠す
            for(var j = 0; j < this.menuNum; j ++){
                document.getElementById(this.idPrefixName + j).style.top  = -1000;
                document.getElementById(this.idPrefixName + j).style.left = -1000;
            }
            this.visible = false;
        }
    }

    /**
     * 画像を点滅後別のページに移動する
     */
    this.startMovePage = function () {
        this.blinkCount = 0;
        this.movePageId = setInterval((function(){this.movePage()}).bind(this),200);
    }
    	
    /**
     * 画像を点滅後別のページに移動する
     */
    this.movePage = function () {
        this.blinkCount = this.blinkCount + 1;
        document.getElementById(this.idPrefixName + this.selectedId).style.visibility = (document.getElementById(this.idPrefixName + this.selectedId).style.visibility == "visible") ? "hidden" : "visible";

        if(this.blinkCount >= this.maxBlinkCount){
            clearInterval(this.movePageId);
            document.getElementById(this.idPrefixName + this.selectedId).style.visibility = 'visible';
            
            setTimeout((function(){location.href = this.url[this.selectedId];}).bind(this),500);
        }
    }

    /**
     * メニューを回転させる
     */
    this.startRoleMenu = function (direction){
        if(direction == 'left'){
            this.roleCount = 0;
            this.selectedId = (this.selectedId + 1) % this.menuNum;//左にずらす
            this.roleId = setInterval((function(){this.roleMenu('left')}).bind(this),this.feedInterval);
        }
        if(direction == 'right'){
            this.roleCount = 0;
            this.selectedId = (this.selectedId + this.menuNum - 1) % this.menuNum;//右にずらす
            this.roleId = setInterval((function(){this.roleMenu('right')}).bind(this),this.feedInterval);
        }
    }
	
    /**
     * メニューを回転させる
     */
    this.roleMenu = function (direction){
        //実行回数をインクリメント
        this.roleCount = this.roleCount + 1;
        //
        var angle = 0;
        if(direction == 'left'){
            angle = (360/this.menuNum)*((this.maxRoleCount - this.roleCount)/this.maxRoleCount)*-1;//角度
        }
        else{
            angle = (360/this.menuNum)*((this.maxRoleCount - this.roleCount)/this.maxRoleCount);//角度
        }
        //
        for(var j = 0; j < this.menuNum; j ++){
            var angleIndex = (j - this.selectedId + this.menuNum)%this.menuNum;//アイコンの角度
            document.getElementById(this.idPrefixName + j).style.left = this.posX - this.image[j].width/2  + this.minRadius*Math.cos((this.angle[angleIndex] + angle)/180*Math.PI);
            document.getElementById(this.idPrefixName + j).style.top  = this.posY - this.image[j].height/2 - this.minRadius*Math.sin((this.angle[angleIndex] + angle)/180*Math.PI);
        }
        //規定の回数に達したら停止
        if(this.roleCount >= this.maxRoleCount){
            clearInterval(this.roleId);
            this.roleId = '';
            this.frameShow();
        }
    }

    /**
     * 枠を表示する
     */
    this.frameShow = function (){
        if(this.frameImage != ''){
            var w = this.frameImage.width;
            var l = this.frameImage.height;
            var baseX = this.posX - this.image[this.selectedId].width/2;
            var baseY = this.posY - this.image[this.selectedId].height/2 - this.minRadius;
            //
            for(var i = 0; i < 4; i ++){
                //this.framePostfixName = new Array("TL","TR","BL","BR");
                if(i == 0){
                    document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.left = baseX;
                    document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.top  = baseY;
                }
                else if(i == 1){
                    document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.left = baseX + (this.image[this.selectedId].width - w);
                    document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.top  = baseY;
                    
                }
                else if(i == 2){
                    document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.left = baseX;
                    document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.top  = baseY + (this.image[this.selectedId].height - l);
                }
                else if(i == 3){
                    document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.left = baseX + (this.image[this.selectedId].width - w);
                    document.getElementById(this.idPrefixName + this.framePostfixName[i]).style.top  = baseY + (this.image[this.selectedId].height - l);
                }
            }
        }
    }

    /**
     * キーを押したときに実行される
     */
    this.keyPressEvent = function(event){
        //フェード中でなく表示中の場合イベントを受理
        if(this.feedInId == '' && this.visible == true && this.feedOutId == ''){
            if((this.roleId == '' || this.roleId == null) && event.keyCode == 38){
                this.startRoleMenu('left');
            }
            if((this.roleId == '' || this.roleId == null) && event.keyCode == 40){
                this.startRoleMenu('right');
            }
            //エンター
            if(event.keyCode == 13){
                //location.href = this.url[this.selectedId];;
            	this.startMovePage();
            }
        }
        //フェード中または表示中はイベントを受け付けない
        if(this.feedInId != '' || this.visible == true || this.feedOutId != ''){
            //起動時はイベントを無視する
            Event.stop(event);
            //opera用
            try{
                event.returnValue = false;
                event.preventDefault();
            }
            catch(e){
            }
        }
    }

    /**
	 * クリック(mousedown)したときに実行される
     */
    this.clickEvent = function(event){
        //
    	if(this.visible == true || this.feedOutId != ''){
    		if(Event.isLeftClick(event) && this.movePageId == ''){
    			this.startMovePage();
    		}
    		if(Event.isRightClick(event) && this.feedOutId == ''){
    			this.startFeedOut();
    		}
    		//起動時はイベントを無視する
            Event.stop(event);
        }
    }


    /**
	 * 右クリック(contextmenu表示)したときに実行される
     */
    this.contextMenuEvent = function(event){
        //
    	if(this.visible == true || this.feedOutId != ''){
    		//起動時はイベントを無視する
            Event.stop(event);
        }
    }
	
    /**
     * ダブルクリックしたときに実行される
     */
    this.dblClickEvent = function(event){
        //二度実行しない,フェードイン中でない
        if(this.visible == false && this.feedInId == ''){
            //選択範囲の解除
            try{
                //IE
                if(document.selection){
                    var selection = document.selection.createRange();
                	//StartToEnd:選択範囲の始点を終点と同じ位置にすることで
                	//ダブルクリックの範囲選択を解除する
                	//※EndToStartだとページが上に遷移する
                    selection.setEndPoint("StartToEnd", selection);
                    selection.select();
                }
            }catch(e){
                ;
            }
            //firefox
            try{
                var selection = window.getSelection();
                selection.collapse(document.body, 0);
            }catch(e){
                ;
            }
            //座標の取得
            this.posX = Event.pointerX(event);
            this.posY = Event.pointerY(event);
            this.startFeedIn();
        }
    }
    
    /**
     * ホイールを押したときに実行される
     */
    this.mouseWheelEvent = function (event) {
        //フェード中でなく表示中の場合イベントを受理
        if(this.feedInId == '' && this.visible == true && this.feedOutId == ''){
            if((event.detail ? event.detail : event.wheelDelta) >= 0){
                if(this.roleId == '' || this.roleId == null){
                    this.roleCount = 0;
                    this.selectedId = (this.selectedId + 1) % this.menuNum;//左にずらす
                    this.roleId = setInterval((function(){this.roleMenu('left')}).bind(this),this.feedInterval);
                }
            }
            
            if((event.detail ? event.detail : event.wheelDelta) < 0){
                if(this.roleId == '' || this.roleId == null){
                    this.roleCount = 0;
                    this.selectedId = (this.selectedId + this.menuNum - 1) % this.menuNum;//右にずらす
                    this.roleId = setInterval((function(){this.roleMenu('right')}).bind(this),this.feedInterval);
                    event.returnValue = false;
                }
            }
        }
        //フェード中または表示中はイベントを受け付けない
        if(this.feedInId != '' || this.visible == true || this.feedOutId != ''){
            //起動時はイベントを無視する
            Event.stop(event);
        }
    }
    /**
     * mouseを動かしたときに実行される
     */
    this.mouseMoveEvent = function(event){
        //フェードインの後でフェードアウト中でない
        if((this.feedInId != '' || this.visible == true) && this.feedOutId == ''){
            var diff = this.minRadius + 50;
            if( Event.pointerX(event) < this.posX - diff || this.posX + diff < Event.pointerX(event) 
                    || Event.pointerY(event) < this.posY -diff || this.posY + diff < Event.pointerY(event) ){
                this.startFeedOut();
            }
        }
    }
}