<?php
/**
 * @copyright © 2007, 2008, 2009 Intrahealth International, Inc.
 * This File is part of I2CE
 *
 * I2CE is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * Default Admin Page
 *
 * @package I2CE
 * @subpackage Core
 * @author Carl Leitner <litlfred@ibiblio.org>
 * @version 2.1
 * @access public
 */

class I2CE_Page_MagicDataBrowser extends I2CE_Page {

        

    /**
     * @var protected array $config_path array of strings.  the configuration path requested for this page.
     */
    protected $config_path;

    /**
     * @var I2CE_MagicData protected The magic data pointed to by the config path
     */
    protected $config;
    
    /**
     * Constructor -- called from page wrangler for URL of form admin/(module_name)/action/arg1/arg2
     * @param string $shortname A module name to show the admin page for. Defaults to null to mean no module.
     * @param string $action The action this pages is to perform
     * @param array $args an array of strings
     * @param string $message. A message to display on the page.  Defaults to null
     */
    public function __construct($args,$request_remainder) {
        parent::__construct($args,$request_remainder);
        $this->config_path = $request_remainder;
        $this->config = I2CE::getConfig()->traverse('/'.implode('/',$this->config_path),false,false);
    }


    protected function reshow($parent = false) {
        if ($parent) {
            $path = $this->config_path;
            array_pop($path);
            $path = implode('/',$path);
        } else   if ($this->get_exists('caller')) {
            $path = $this->get('caller');
        }  else if ($this->post_exists('caller')) {
            $path = $this->post('caller');
        } else {
            $path = implode('/',$this->config_path);
        }
        $url = $this->module() .'/show/' .$path;
        $this->setRedirect($url);
    }


    /*
     * Perform the actions for this page
     */
    protected function action() {
        parent::action();
        if (!$this->config instanceof I2CE_MagicDataNode) {
            $this->reshow(true); //show the parent node.
            return;
        }
        switch($this->page()) {
        case 'erase':
            $name = $this->config->getName();
            $parent = $this->config->traverse('../');
            if ($this->isPost() && ($this->config->getPath() != $this->config->traverse('/')->getPath())) { //don't allow an erase of the top level node
                unset($parent->$name);
            }
            $this->reshow(true);
            break;
        case 'parent':
            if ($this->isPost() && $this->config->is_indeterminate()) {
                $this->config->set_parent();
            }
            $this->reshow();
            break;
        case 'scalar':
            if ($this->isPost() && $this->config->is_indeterminate()) {
                $this->config->set_scalar();
            }
            $this->reshow();
            break;
        case 'add':
            if ($this->post_exists('browser_magic_data_add_key')) {
                $key = $this->post('browser_magic_data_add_key');
                if (I2CE_MagicDataNode::checkKey($key) && !$this->config->pathExists($key)) {
                    $this->config->traverse($key,true,false);
                }
            }
            $this->reshow();
            break;
        case 'set':
            if ($this->post_exists('browser_magic_data_value') && $this->post_exists('browser_magic_data_key')) {
                $key = $this->post('browser_magic_data_key');
                $value = $this->post('browser_magic_data_value');
                if ($this->config->offsetExists($key) && is_scalar($value)) {
                    if ($this->config->is_translatable($key)) {
                        $locales = I2CE_Locales::getPreferredLocales();
                        reset($locales);
                        $locale = current($locales);
                        $this->config->setTranslation($locale,$value,$key);
                        if ($locale == I2CE_Locales::DEFAULT_LOCALE) {
                            $this->config->__set($key, $value);
                        }
                    } else {
                        $this->config[$key] = $value;
                    }
                }
            }
            //we redirect so a reload does not post and so that if the page's display depends on the value that is being
            //set, we redisplay it.
            $this->reshow();
            break;
        case 'show':                    
        case 'mini':                    
            $this->actionDisplayConfig();
            break;
        default:
            $this->reshow();
        }
    }


        


    protected function displayConfig($config,$magicNode,$full) {
        foreach ($config as $key=>$child) {
            if($config->is_parent($key)) {
                $path = 'magicDataBrowser/show/' . $config->getPath(false);
                $node = $this->template->loadFile("browser_node.html",'li');
                $magicNode->appendChild($node);
                $this->template->setDisplayDataImmediate('erase_action','magicDataBrowser/erase/'. $config->getPath(false) . "/$key",$node);
                $subNode = $this->template->query( "./descendant-or-self::node()[@name='magic_data_list']",$node);
                $this->template->setDisplayDataImmediate('browser_magic_data_key_path',$path.'/'.$key,$node);
                $this->template->setDisplayDataImmediate('browser_magic_data_key',$key,$node); 
                if ($full && $subNode->length > 0) {
                    $this->displayConfig($child,$subNode->item(0),$full); 
                } else {
                    $valueNode = $this->template->getElementById('browser_magic_data_value',$node);
                    if (!$valueNode instanceof DOMElement) {
                        continue;
                    }
                    if ($this->hasAjax()) {
                        $replacementNode = $this->template->createElement('span',
                                                                          array('class'=>'clickable',
                                                                                'id'=>"magic_data_list_$path/$key"
                                                                              ), 
                                                                          'show values' 
                            ); 
                        $this->addAjaxUpdate("magic_data_list_$path/$key",
                                             "magic_data_list_$path/$key",
                                             'click',
                                             "$path/$key",
                                             'magic_data_list'
                            );
                        $this->addAjaxCompleteFunction("magic_data_list_$path/$key",
                                                             "$('magic_data_list_$path/$key').removeClass('clickable')"
                            );
                    } else {
                        $replacementNode = $this->template->createTextNode('*******');
                    }
                    $valueNode->parentNode->replaceChild($replacementNode,$valueNode);
                }
            } else    if($config->is_scalar($key)) {
                //just display the value
                $valueNode = $this->template->loadFile("browser_value_node.html",'li');
                $magicNode->appendChild($valueNode);
                $locale = '';
                if ($config->is_translatable($key)) {
                    if ($this->request_exists('locale')) {
                        $locale = $this->request('locale');
                    } else {
                        $locales = I2CE_Locales::getPreferredLocales();
                        reset($locales);
                        $locale = current($locales);
                    }
                    $child = $config->getTranslation($locale,false,$key);
                    $locale = ' [' . $locale . ']';

                }
                $this->template->setDisplayDataImmediate('browser_magic_data_key',$key,$valueNode);
                $this->template->setDisplayDataImmediate('browser_magic_data_key_label',$key . $locale,$valueNode);
                $this->template->setDisplayDataImmediate('browser_magic_data_value',$child,$valueNode);
                $this->template->setDisplayDataImmediate('change_value_action','magicDataBrowser/set/'. $config->getPath(false) ,$valueNode);
                $this->template->setDisplayDataImmediate('erase_action','magicDataBrowser/erase/'. $config->getPath(false) . "/$key",$valueNode);
            } else if( $config->is_indeterminate($key)) {
                $valueNode = $this->template->loadFile("browser_value_node_notset.html",'li');
                $magicNode->appendChild($valueNode);
                $this->template->setDisplayDataImmediate('browser_magic_data_key',$key,$valueNode);
                $this->template->setDisplayDataImmediate('erase_action','magicDataBrowser/erase/'. $config->getPath(false) . "/$key",$valueNode);
                $this->template->setDisplayDataImmediate('parent_action','magicDataBrowser/parent/'. $config->getPath(false) . "/$key",$valueNode);
                $this->template->setDisplayDataImmediate('scalar_action','magicDataBrowser/scalar/'. $config->getPath(false) . "/$key",$valueNode);
            } else {
                //echo "weird $key\n";
            }
        }
        $valueNode = $this->template->loadFile("browser_add_node.html",'li');        
        if ($valueNode instanceof DOMElement) {
            $magicNode->appendChild($valueNode);
            $this->template->setDisplayDataImmediate('add_key_action','magicDataBrowser/add/'. $config->getPath(false),$valueNode);
        }
        $url_tail = implode('/',$this->config_path);
        if ($this->get_exists('full')) {
            $url_tail .= '?full';
        }
        $this->template->setDisplayDataImmediate('caller',$url_tail,$magicNode);
    }



    function displayConfigMini($config,$magicNode,$full) {
        foreach ($config as $key=>$child) {
            if($config->is_parent($key)) {
                $path = 'magicDataBrowser/mini/' . $config->getPath(false);
                $node = $this->template->loadFile("browser_node_mini.html",'li');
                $magicNode->appendChild($node);
                $this->template->setDisplayDataImmediate('erase_action','magicDataBrowser/erase/'. $config->getPath(false) . "/$key",$node);
                $subNode = $this->template->query( "./descendant-or-self::node()[@name='magic_data_list']",$node);
                $this->template->setDisplayDataImmediate('browser_magic_data_key_path',$path.'/'.$key,$node);
                $this->template->setDisplayDataImmediate('browser_magic_data_key',$key,$node); 
                if ($full && $subNode->length > 0) {
                    $this->displayConfigMini($child,$subNode->item(0),$full); 
                } else {
                    $valueNode = $this->template->getElementById('browser_magic_data_value',$node);
                    if (!$valueNode instanceof DOMElement) {
                        continue;
                    }
                    if ($this->hasAjax()) {
                        $replacementNode = $this->template->createElement('span',
                                                                          array('class'=>'clickable',
                                                                                'id'=>"magic_data_list_$path/$key"
                                                                              ), 
                                                                          'show values' 
                            ); 
                        $this->addAjaxUpdate("magic_data_list_$path/$key",
                                             "magic_data_list_$path/$key",
                                             'click',
                                             "$path/$key",
                                             'magic_data_list'
                            );
                        $this->addAjaxCompleteFunction("magic_data_list_$path/$key",
                                                             "$('magic_data_list_$path/$key').removeClass('clickable')"
                            );
                    } else {
                        $replacementNode = $this->template->createTextNode('*******');
                    }
                    $valueNode->parentNode->replaceChild($replacementNode,$valueNode);
                }
            } else    if($config->is_scalar($key)) {
                //just display the value
                $valueNode = $this->template->loadFile("browser_value_node_mini.html",'li');
                $magicNode->appendChild($valueNode);
                $this->template->setDisplayDataImmediate('browser_magic_data_key',$key,$valueNode);
                $this->template->setDisplayDataImmediate('browser_magic_data_value',$child,$valueNode);
            } else if( $config->is_indeterminate($key)) {
                $valueNode = $this->template->loadFile("browser_value_node_notset_mini.html",'li');
                $magicNode->appendChild($valueNode);
                $this->template->setDisplayDataImmediate('browser_magic_data_key',$key,$valueNode);
                $this->template->setDisplayDataImmediate('parent_action','magicDataBrowser/parent/'. $config->getPath(false) . "/$key",$valueNode);
                $this->template->setDisplayDataImmediate('scalar_action','magicDataBrowser/scalar/'. $config->getPath(false) . "/$key",$valueNode);
            } else {
                //echo "weird $key\n";
            }
        }       
    }


    protected function actionDisplayConfig() {
        $this->template->setBodyId( "magicDataBrowserPage" );
        $this->template->addHeaderLink("MagicDataBrowser.css");
        if ($this->hasAjax() === true) {
            $this->template->addHeaderLink("mootools-core.js");
        }
        $path =  $this->config->getPath(false);
        $magicNode = $this->template->addFile( "browser.html", "div" );
        $this->template->setAttribute( "class", "active", "menuConfigure", "a[@href='configure']" );
        $this->template->appendFileById( "menu_configure.html", "ul", "menuConfigure" );
        $this->template->setAttribute( "class", "active", "menuBrowseMagicData", "a[@href='magicDataBrowser/{$this->page}']" );
        if (I2CE_ModuleFactory::instance()->isEnabled('magicDataExport')) {
            $exportNode = $this->template->addFile( "magicdata_export_controls.html", "div" );
            if ($exportNode instanceof DOMNode) {
                $this->template->addFormWorm('magicdata_export_form');
                $this->template->setDisplayDataImmediate('config_path', $path, $exportNode);
                $this->template->setDisplayDataImmediate('version', '1.0.' . date("Y") . '.' . date("m") . '.' . date("d"), $exportNode);
            }
        }
        $config_path_node = $this->template->getElementById('config_path_display');
        if ($config_path_node instanceof DOMNode) {
            $path_components = explode('/',$path);
            $t_path = '';
            foreach ($path_components as $path_component) {
                $t_path .=  $path_component .'/';
                $config_path_node->appendChild($this->template->createTextNode(' '));
                $attrs = array('href'=>'magicDataBrowser/' . $this->page   . $t_path);
                $config_path_node->appendChild($this->template->createElement('a',$attrs,$path_component .'/'));
            }

        }
        if (!$this->get_exists('full')) { 
            $this->template->setDisplayDataImmediate('full_view','magicDataBrowser/' . $this->page .   $path .'?full' , $magicNode); 
            $this->template->setDisplayDataImmediate('compressed_view','');
            if ($this->page == 'mini') {
                $this->template->setDisplayDataImmediate('nomini_view','magicDataBrowser/show'.   $path  , $magicNode); 
                $this->template->setDisplayDataImmediate('mini_view','');
            } else {
                $this->template->setDisplayDataImmediate('mini_view','magicDataBrowser/mini'.   $path  , $magicNode); 
                $this->template->setDisplayDataImmediate('nomini_view','');
            }
        } else {
            $this->template->setDisplayDataImmediate('compressed_view','magicDataBrowser/' . $this->page  . $path  , $magicNode); 
            $this->template->setDisplayDataImmediate('full_view','');
            if ($this->page == 'mini') {
                $this->template->setDisplayDataImmediate('nomini_view','magicDataBrowser/show'.   $path  .'?full' , $magicNode); 
                $this->template->setDisplayDataImmediate('mini_view','');
            } else {
                $this->template->setDisplayDataImmediate('mini_view','magicDataBrowser/mini'.   $path .'?full' , $magicNode); 
                $this->template->setDisplayDataImmediate('nomini_view','');
            }
        }
        if ($path !== $this->config->traverse('/')->getPath(false)) {
            $actionNodeList = $this->template->query("//*[@id='magicdata_erase']");
            for ($i=0; $i < $actionNodeList->length; $i++) {
                $actionNodeList->item($i)->setAttribute('action','magicDataBrowser/erase/' . $path);
            }
        } else {
            $this->template->removeNodeById('magicdata_erase');
        }
        $actionNodeList = $this->template->query("//*[@id='magicdata_export']");
        for ($i=0; $i < $actionNodeList->length; $i++) {
            $actionNodeList->item($i)->setAttribute('action','magicDataExport/export/' . $path);
        }
        $magicListNode =$this->template->query( "./descendant-or-self::node()[@name='magic_data_list']",$magicNode);
        if ($magicListNode->length > 0) {
            if ($this->page == 'mini') {
                $this->displayConfigMini($this->config,$magicListNode->item(0) ,$this->get_exists('full'));  
            } else {
                $this->displayConfig($this->config,$magicListNode->item(0) ,$this->get_exists('full'));  
            }
        }

    }



}

# Local Variables:
# mode: php
# c-default-style: "bsd"
# indent-tabs-mode: nil
# c-basic-offset: 4
# End:
