<?php
    //========================================================================================================================
    /**
     * MVCビュークラス：Ajaxビュー
     *
     * リクエスト変数($_REQUEST)のラッパークラス
     *
     * LICENSE: This source file is subject to GNU GENERAL PUBLIC LICENSE Version 3
     * http://www.gnu.org/licenses/gpl-3.0.txt.
     *
     * @package    LabbitBox
     * @subpackage core
     * @copyright  2010 LabbitBox Development Team.
     * @license    GPL v3 http://www.gnu.org/licenses/gpl-3.0.txt
     * @author     neobaba <neobaba@labbitbox.org>
     * @version    v0.1
     * @since      2010/2/26
     * @link       http://labbitbox.org/
     * @see        http://labbitbox.org/
     */
    //========================================================================================================================
    require_once(BASE_LIB.'/ClientView.php');

    class EmbededView extends ClientView {
        protected $_mode          = ''   ; //実行モード:REGION/AJAX 
        protected $_topRegion     = NULL ;
        protected $_model         = NULL ;
        protected $_prefix        = ''   ;
        protected $_suffix        = ''   ;
        protected $_extendParams  = NULL ; //拡張パラメータ(データ構造は実装仕様に従う)

        /**
         * コンストラクタ/デストラクタ
         * @param object    $parent         生成元ビューオブジェクト
         * @param object    $application    アプリケーションオブジェクト
         * @param string    $templateName   テンプレートファイル名
         * @param string    $mode           実行モード:REGION/AJAX
         * @param string    $templateDir    テンプレート格納ディレクトリ
         * @param mixed     $extendParams   拡張パラメータ(データ構造は実装仕様に従う)
         */
        public function __construct($parent, $application, $templateName, $mode = '', $templateDir = '', $extendParams=NULL){
            parent::__construct($application, $templateName, $templateDir);
            $this->_className   = 'EmbededView';

            $this->_mode        = ($mode !== '' ? $mode : $parent->mode());
            if ($this->_mode == 'REGION'){
                $this->_parent      = $parent;
            }
            $this->_topRegion      = $parent->getTopRegion();
            $this->_extendParams = $extendParams;

            //----------------------------------------------------------------------------------------------------------------
            //モデルオブジェクト生成
            $wkModelClassName   = $this->name.'_M';
            $wkModelFilePath    = PRJHOME.'/'.$wkModelClassName.'.php';
            if (file_exists($wkModelFilePath)){
                require_once($wkModelFilePath);
                $this->_model   = new $wkModelClassName($this->_app, $this->_mode, $this->_extendParams);
            }
        }

        /**
         * 最上位Regionオブジェクト取得
         * @return Object リージョンオブジェクト
         */
        public function topRegion(){
            return ( $this->_mode === 'REGION' ? $this->_parent : $this );
        }

        /**
         * 上位ビューオブジェクト取得
         * @return Object ビューオブジェクト
         */
        public function parent(){
            return $this->_parent;
        }

        /**
         * 実行モード取得
         * @return string   実行モード:REGION/AJAX   
         */
        public function mode(){
            return $this->_mode;
        }

        /**
         * プレフィクス設定
         * @param string    $prefix エレメントIDの先頭に付加する文字列
         */
        public function appendPrefix($prefix){
            $this->_prefix  = $prefix;    
        }

        /**
         * サフィクス設定
         * @param string    $suffix エレメントIDの末尾に付加する文字列
         */
        public function appendSuffix($suffix){
            $this->_suffix  = $suffix;
        }

        /**
         * レスポンス文字列生成
         * 自DOMオブジェクトからHTML文字列に展開する
         *
         * @return string   HTML文字列
         */
        public function build(){
            if ($this->_topRegion->className() == 'HtmlView'){
                Region::build();
            }
            else{
                parent::build();
            }

            //Prefix/suffix付加
            if ($this->_prefix != '' || $this->_suffix != ''){
                $this->_appendFix($this->_doc->getElementsByTagName('body')->item(0));
            }

            return $this->_doc;
        }

        /**
         * プレフィクス/サフィクス付加
         * @param string    $node   付加対象ノード
         */
        private function _appendFix($node){
            //Prefix/suffix付加
            foreach($node->childNodes as $_childNode){
                if ($_childNode->nodeType == XML_ELEMENT_NODE){
                    if (count($_childNode->childNodes)){
                        $this->_appendFix($_childNode);
                    }

                    if ($_childNode->hasAttribute('id')){
                        $_childNode->setAttribute('id', $this->_prefix.'_'.$_childNode->getAttribute('id').'_'.$this->_suffix);
                    }
                }
            }
        }

        /**
         * meta定義追加
         * <head>にmeta定義を追加する
         *
         * @param string    $key    キー(連想配列の場合は値は不要)
         * @param array     $value  値
         */
        public function addMeta($key, $value = NULL){
            if ($this->_topRegion->className() == 'HtmlView'){
                $this->_topRegion->addMeta($key, $value);
            }
            else{
                parent::addMeta($key, $value);
            }
        }
        
        /**
         * CSSファイルインクルード定義追加
         * <head>に外部CSSファイルへのリンクタグを追加する
         *
         * @param string    $agCSSName      CSS名(.cssは付けない)
         * @param string    $agCSSDir       CSSパス:省略時は'css'
         */
        public function addCssLink($agCSSName, $agCSSDir = 'css'){
            if ($this->_topRegion->className() == 'HtmlView'){
                $this->_topRegion->addCssLink($agCSSName, $agCSSDir);
            }
            else{
                parent::addCssLink($agCSSName, $agCSSDir);
            }
        }

        /**
         * CSS定義追加
         * <head>にstyleのクラス定義を追加する
         *
         * @param string    $agEntryName    クラス名
         * @param array     $agStyleList    スタイルの連想配列
         */
        public function addStyleCss($entryName, $styles){
            if ($this->_topRegion->className() == 'HtmlView'){
                $this->_topRegion->addStyleCss($entryName, $styles);
            }
            else{
                parent::addStyleCss($entryName, $styles);
            }
        }

        /**
         * CSS定義追加
         * <head>にstyleのクラス定義を追加する
         *
         * @param string    $agClassName    クラス名
         * @param array     $styleList      スタイルの連想配列
         */
        public function addStyleCssList($styleCssList){
            if ($this->_topRegion->className() == 'HtmlView'){
                $this->_topRegion->addStyleCssList($styleCssList);
            }
            else{
                parent::addStyleCssList($styleCssList);
            }
        }

        /**
         * Javascriptインクルード定義追加
         * <head>に外部Javascriptファイルのインクルードタグを追加する
         *
         * @param string    $agJsFilePath   外部Javascriptファイルパス
         */
        public function addJsInclude($agJsFilePath){
            if ($this->_topRegion->className() == 'HtmlView'){
                $this->_topRegion->addJsInclude($agJsFilePath);
            }
            else{
                parent::addJsInclude($agJsFilePath);
            }
        }

        /**
         * ページロード時実行スクリプト定義追加
         * <head>に外部Javascriptファイルのインクルードタグを追加する
         *
         * @param string    $function 関数名
         * @param string    $args     引数群(引数イメージを文字列で：例(引数3個の場合)'a, b, c')
         */
        
        public function addLoadJsFunction($function, $args = ''){
            if ($this->_topRegion->className() == 'HtmlView'){
                $this->_topRegion->addLoadJsFunction($function, $args);
            }
            else{
                parent::addLoadJsFunction($function, $args);
            }
        }

        public function addLoadJs($script){
            if ($this->_topRegion->className() == 'HtmlView'){
                $this->_topRegion->addLoadJs($script);
            }
            else{
                parent::addLoadJs($script);
            }
        }

        /**
         * Javascript関数定義追加
         * <head>にJavascript関数を直接記述
         *
         * @param string    $function   関数名
         * @param string    $args       引数群(引数イメージを文字列で：例(引数3個の場合)"10, 'abc', 5")
         * @param string    $script     関数の実行コード
         */
        public function addJsFunction($function, $args, $script){
            if ($this->_topRegion->className() == 'HtmlView'){
                $this->_topRegion->addJsFunction($function, $args, $script);
            }
            else{
                parent::addJsFunction($function, $args, $script);
            }
        }

        /**
         * Javascript定義追加
         * <head>にJavascript関数を直接記述
         *
         * @param array     $script     スクリプトの実行コード
         */
        public function addJsScript($script){
            if ($this->_topRegion->className() == 'HtmlView'){
                $this->_topRegion->addJsScript($script);
            }
            else{
                parent::addJsScript($script);
            }
        }

    }
?>
