/**
 * YUIのPanel widgetを似た構造を、Panel widgetの上位クラス(YAHOO.widget.Module)を使い、独自実装したもの
 * Plate coreと呼ぶ
 * 
 * require YUI js list 
 * <script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/yahoo-dom-event/yahoo-dom-event.js"></script> 
 * <script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/connection/connection-min.js"></script> 
 * <script type="text/javascript" src="http://yui.yahooapis.com/2.6.0/build/dragdrop/dragdrop-min.js"></script>
 */
/**
 * Panel Widgetを組み込むためのJS
 *
 * configDlgを必ず使うかどうかは要検討。panelではなくplateと名前を変えたほうがいいかも
 * <p>
 * このJSを読み込むと、class="panel"の要素(以下panelルート)をpanelウィジェットにしようとする。
 * panelウィジェットになるとボタンがつけられいくつかの機能が自動的に実装される。
 * </p>
 *　<code>
 *   <div class="panel">
 *     <div class="hd">
 *     </div>
 *     <div class="bd">
 *     </div>
 *     <div class="ft">
 *     </div>
 *   </div>
 * </code>
 * のようにマークアップされていることが前提で実装されており、class名を正しく一致させる必要があるが
 * それ以外には特に求められない。
 *
 * オプションとしてpanelルート以下に特定のclass名を持つタグをマークアップするといくつかの機能が追加される。
 * container-close
 * クリックしたpanelを閉じる機能
 *
 * container-config
 * クリックしたpanelに結びついているプレートの設定ダイアログの表示
 *
 * container-minmax
 * クリックしたpanelをheaderだけになるの表示になる
 */


(function(){
    new PadPlate.util.Loader({
        require: ["connection","containercore"], // what to load
        onSuccess: function(o) {
            init();
        }
    });

    function init(){
        var Dom     = YAHOO.util.Dom,
            Event   = YAHOO.util.Event,
            Connect = YAHOO.util.Connect,
            Module  = YAHOO.widget.Module;
        
//        PadPlate.namespace('plate');
        PadPlate.plate = {};
        PadPlate.plate.run = function(){
            // IEではXPathがnativeに実装されていないので*で具体的なタグを指定しないと数倍遅くなる
            var panelElements = PadPlate.util.getElementsByClassName( 'box-YUIpanel', 'div', document.body );
            var elementLen = panelElements.length;
            for( var i=0; i<elementLen; ++i ){
                var element = panelElements[i];
                panel = PadPlate.plate.create( element );
            }
        };
        PadPlate.plate.create = function( target ){
            myPanel = new Module(target);
            myPanel.render();
            // 最小化ボタン
            var minmaxBtn = registerButton( target, myPanel, "container-minmax", {
                toggle : function(ev){
                    display = '';
                    if( Dom.hasClass(this.element,"js-minimum") ){
                        Dom.removeClass( this.element, "js-minimum" );
                    }else{
                        Dom.addClass( this.element, "js-minimum" );
                        display = 'js-minimum';
                    }
                    var panelId = this.element.getAttribute('id').substr('var-panelId'.length + 1);
                    plateId = panelId;
                    Connect.asyncRequest(
                        'POST',
                        "./ajax/update_plate_minimum.php", {
                            success: function( httpObj ){
                                response = eval( "("+httpObj.responseText+")" );
                                if( response["status"] != "success" ){
                                    alert(response["result"]);
                                    return;
                                }
                            }
                        },
                        "plateId="+plateId+"&minimum="+display
                    );
                    Event.stopEvent(ev);
                }
            }, 'toggle' );
            if( minmaxBtn != false ){
                if( Dom.hasClass(myPanel.element,"js-minimum") ){
                    //minmaxBtn.toggle();
                    minmaxBtn.setStatus('toggled');
                }
                /**
                 * プレートのタイトルバーをダブルクリックしたとき最小化する
                 * @todo 今の実装だと設定ダイアログをダブルクリックしても起動してしまう
                 */
                Event.on( myPanel.header, 'click', function(ev){
                        minmaxBtn.onToggle.fire();
                    }
                );
            }
            return myPanel;
        }
        
        /**
         * 指定したクラス名にイベントを結びつける
         *
         * @param string type ボタンタイプ(無指定なら通常ボタン)
         * @todo 毎回ifで判定するのでそこを最適化できる
         */
        function registerButton( panelElement, panel, className, config, type ){
            btnEl = PadPlate.util.getElementByClassName( className, 'span', panelElement, function( element ){
                return element;
            } );
        
            if( btnEl == undefined ){
                return undefined;
            }
            if( type == 'toggle' )
                return new PanelMenuToggleButton( btnEl, panel, config );
            else
                return new PanelMenuButton( btnEl, panel, config );
        }
        
        /**
         * 指定したパネルに属するボタンウィジェット
         *
         * @param 追加するボタンのelement node
         * @param 属するpanel
         * @param オプション値
         */
        var PanelMenuButton = function( element, panel, config ){
            if( typeof config.click == "function" )
                Event.on( element, 'click', config.click, panel, true );
            
            Event.on( element, 'mouseover', function(){
                Dom.addClass( this, "mouseover" );
            });
            Event.on( element, 'mouseout', function(){
                Dom.removeClass( this, "mouseover" );
                Dom.removeClass( this, "mousedown" );
            });
            Event.on( element, 'mousedown', function(){
                Dom.addClass( this, "mousedown" );
            });
            Event.on( element, 'mouseup', function(){
                Dom.removeClass( this, "mousedown" );
            });
        }
        
        /**
         * 指定したパネルに属するトグルボタンウィジェット
         *
         * @param 追加するボタンのelement node
         * @param 属するpanel
         * @param オプション値
         */
        var PanelMenuToggleButton = function( element, panel, config ){
            this.element = element;
            this.onToggle = new YAHOO.util.CustomEvent("onToggle", this);
            this.onToggle.subscribe( function(){
                if( Dom.hasClass(this.element, 'toggled') )
                    Dom.removeClass(this.element, 'toggled');
                else
                    Dom.addClass(this.element, 'toggled');
            }, this );
            if( typeof config.toggle == "function" )
                this.onToggle.subscribe( config.toggle, panel, true );
        
            Event.on( element, 'click', function(ev){
                this.onToggle.fire();
            }, this, true);
            Event.on( element, 'mouseover', function(){
                Dom.addClass( this, "mouseover" );
            });
            Event.on( element, 'mouseout', function(){
                Dom.removeClass( this, "mouseover" );
            });
            Event.on( element, 'mousedown', function(){
                Dom.addClass( this, "mousedown" );
            });
            Event.on( element, 'mouseup', function(){
                Dom.removeClass( this, "mousedown" );
            });
        }
        PanelMenuToggleButton.prototype = {
            toggle : function(){
                if( Dom.hasClass(this.element, 'toggled') )
                    Dom.removeClass(this.element, 'toggled');
                else
                    Dom.addClass(this.element, 'toggled');
            },
            /**
             * 状態を具体的に指定するメソッド
             * @method setStatus
             * @param string status toggledなら押した状態。untoggledなら話した状態に設定する
             * @return void
             */
            setStatus: function(status){
                if(status == 'toggled')
                    Dom.addClass(this.element, 'toggled');
                else if(status == 'untoggled')
                    Dom.removeClass(this.element, 'toggled');
            }
        };
    };
})();