<?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/>.
 */
/**
 *  I2CE_Stub
 * @package I2CE
 * @subpackage Core
 * @author Carl Leitner <litlfred@ibiblio.org>
 * @version 2.1
 * @access public
 */


class I2CE_Stub extends I2CE_Module{
        
    public static function getMethods() {
        return array(
            'I2CE_Page->addAjaxUpdate'=>'addAjaxUpdate',
            'I2CE_Template->addAjaxUpdate'=>'addAjaxUpdate',
            'I2CE_Page->addAjaxToggle'=>'addAjaxToggle',
            'I2CE_Template->addAjaxToggle'=>'addAjaxToggle',
            'I2CE_Page->addAjaxRequestFunction'=>'addAjaxRequestFunction',
            'I2CE_Template->addAjaxRequestFunction'=>'addAjaxRequestFunction',
            'I2CE_Page->addAjaxCompleteFunction'=>'addAjaxCompleteFunction',
            'I2CE_Template->addAjaxCompleteFunction'=>'addAjaxCompleteFunction',

            'I2CE_Page->addAjaxToggleOnFunction'=>'addAjaxToggleOnFunction',
            'I2CE_Template->addAjaxToggleOnFunction'=>'addAjaxToggleOnFunction',
            'I2CE_Page->addAjaxToggleOffFunction'=>'addAjaxToggleOffFunction',
            'I2CE_Template->addAjaxToggleOffFunction'=>'addAjaxToggleOffFunction',

            'I2CE_Page->hasAjax'=>'hasAjaxFuzzy',
            'I2CE_Template->hasAjax'=>'hasAjaxFuzzy'
            ); 
    }  


    public static function getHooks() {
        return array(
            'pre_page_prepare_display_I2CE_Template'=> 'ajaxTest',
            'post_page_prepare_display_I2CE_Template'=> 'writeOutJS',
            );
    }


    public function __construct() {
        parent::__construct();
        $this->js = '';
        if (I2CE_ModuleFactory::instance()->isEnabled('StretchPage')) {
            $this->js .= 'if ( PageStretch ) { PageStretch.stretchPage(); }';
        }
        $this->js_func = '';
    }


    public function ajaxTest($page) {
        if (!isset($_SESSION['stub_ajax_test'])) {
            $_SESSION['stub_ajax_test'] = 'unknown0';
        }
        if (is_bool($_SESSION['stub_ajax_test'])) {
            return;
        } 
        if (preg_match('/^unknown(\d*)/',$_SESSION['stub_ajax_test'],$matches)) {
            if ($matches[1] > 5) {
                $_SESSION['stub_ajax_test'] = false; //assume after 5 page request we never got a response
            } else {
                $matches[1]++;
                $_SESSION['stub_ajax_test'] = 'unknown' . $matches[1];
            }
        } else {
            $_SESSION['stub_ajax_test'] = 'unknown0';
        }
        $stub_url = I2CE_Page::getAccessedBaseURL() . "/stub-ajax";
        $startJS = 
            "
var Stub_Ajax_Test = {
   start: function(){   
        new Request.HTML({url:'$stub_url'}).get();
   }
};
window.addEvent('load',Stub_Ajax_Test.start);
";
        $template = $page->getTemplate();
        $template->addHeaderLink('mootools-core.js');



        $template->addHeaderText($startJS,'script',"stub_ajax_test");
    }

    public static function hasAjax() {
        if (!isset($_SESSION['stub_ajax_test'])) {
            return false;
        }
        if (is_bool($_SESSION['stub_ajax_test'])) {
            return $_SESSION['stub_ajax_test'];
        }
        return false;
    }

    public function hasAjaxFuzzy($obj) {
        return $this->hasAjax();
    }



    /**
     * @param strig  $id_replace is the  id of the node we wish to replace in the page
     * @param string $id_action is the id of the node in the page we wish to add the event to
     * @param string $event is the event we wish to add on
     * @param string $requested_page is the page we wish to make the ajax request from
     * @param_string $id_content is the id of the node we wish to pull the content from in the requested page.
     * @param boolean $js_node boolean -- if true, we will include any javascript generated by the I2CE_Stub in the $request. 
     * $param string $form_id -- if set a the id of form we will pull varaibles from.
     * if it is a string or an array of strings it will concatenate all javascript nodes with id given by the strings and
     * include in the request.  defaults to false meaning do not return any javascript.
     * @param boolean $remove_events. defaults to false.  if true, we remove all events from the action element
     * @param boolean $open. defaults to false.  if true, we remove all event listeners from the action element on the request
     */
    public function addAjaxToggle($obj,$id_replace,$id_action,$event,$requested_page,$id_content,
                                  $js_nodes = false, $form_id='',$remove_events=false,$open=false) {
        $this->addAjaxUpdate($obj,$id_replace,$id_action,$event,$requested_page,$id_content,$js_nodes,$form_id,$remove_events,$open,true);
    }



    /**
     * @param strig  $id_replace is the  id of the node we wish to replace in the page
     * @param string $id_action is the id of the node in the page we wish to add the event to
     * @param string $event is the event we wish to add on
     * @param string $requested_page is the page we wish to make the ajax request from
     * @param_string $id_content is the id of the node we wish to pull the content from in the requested page.
     * @param boolean $js_node boolean -- if true, we will include any javascript generated by the I2CE_Stub in the $request. 
     * $param string $form_id -- if set a the id of form we will pull varaibles from.
     * if it is a string or an array of strings it will concatenate all javascript nodes with id given by the strings and
     * include in the request.  defaults to false meaning do not return any javascript.
     * @param boolean $remove_events. defaults to false.  if true, we remove all events from the action element
     * @param boolean $open. defaults to false.  if true, and not a toggle, we remove all event listeners from the action element on the request
     * @param boolean $toggle.  Defaults to false.  
     */
    public function addAjaxUpdate($obj,$id_replace,$id_action,$event,$requested_page,$id_content,
                                  $js_nodes = false, $form_id='',$remove_events=false,$open=false, $toggle = false) {
        
        $remove_events_on_request = 'false';
        if ($open) {
            $open = 'true';
            if (!$toggle) {
                $remove_events_on_request = 'true';
            }
        } else {
            $open = 'false';
        }
        if ((preg_match('/^[a-zA-Z]+:\/\//',$requested_page))  || ($requested_page[0] == '/')) {
            return;
        }
        if ($js_nodes !== false) {
            if ($js_nodes === true) {
                $js_nodes = '\'stub_events\'';
            } else  if (is_array($js_nodes)) {
                $js_nodes = '\'' . addslashes(implode(',',$js_nodes)) . '\'';
            } else if (!is_scalar($js_nodes)) {
                $js_nodes = 'false';
            } else {
                $js_nodes = "'$js_nodes'";
            }
        } else {
            $js_nodes = 'false';
        }
        $remove_events =  ($remove_events? 'true' : 'false');
        $id_action = addslashes($id_action);
        $id_replace = addslashes($id_replace);
        $id_content = addslashes($id_content);
        $form_id =  addslashes($form_id);
        if ($toggle) {
            $this->js .= "\t\tStub.toggleByIdOnEvent('click','$id_action','$id_replace',"
                . "'{$requested_page}','$id_content','$form_id',$js_nodes,$remove_events, $open);\n";
        } else {
            $this->js .= "\t\tStub.updateByIdOnEvent('click','$id_action','$id_replace',"
                . "'{$requested_page}','$id_content','$form_id',$js_nodes,$remove_events,$remove_events_on_request);\n";
        }
    } 

        
    public function writeOutJS($page) {
        if (empty($this->js) && empty($this->js_func)) { 
            return;
        }
        $startJS = $this->js  . $this->js_func;
        $template = $page->getTemplate();
        $template->addHeaderLink('mootools-core.js');
        $template->addHeaderLink("stubs.js");
        $template->addHeaderLink("stub.css");
        $template->addHeaderText($startJS,'script',"stub_events");
    }


    /**
     * This fuzzy method takes two arguments.  The first arguement is the id of a tag
     * for which there is an event given by addAjaxUpdate.  The second argument is a javascript function to call.
     * Once the addAjaxUpdate request has been competed this function is evaled.
     */
    public function addAjaxCompleteFunction($obj,$id,$func) {
        $this->addAjaxFunction($obj,$id,$func,'complete');
    }


    /**
     * This fuzzy method takes two arguments.  The first arguement is the id of a tag
     * for which there is an event given by addAjaxUpdate.  The second argument is a javascript function to call.
     * on a toggle on starts
     */
    public function addAjaxToggleOnFunction($obj,$id,$func) {
        $this->addAjaxFunction($obj,$id,$func,'on');
    }

    /**
     * This fuzzy method takes two arguments.  The first arguement is the id of a tag
     * for which there is an event given by addAjaxUpdate.  The second argument is a javascript function to call.
     * on a toggle off starts
     */
    public function addAjaxToggleOffFunction($obj,$id,$func) {
        $this->addAjaxFunction($obj,$id,$func,'off');
    }



    protected function addAjaxFunction($obj,$id,$func,$state) {
        $func = preg_replace('{([\'\\\\])}', '\\\\$1', $func);
        $this->js_func .= "\t\tStub.addFunction('$id','$state','$func');\n";
    }

    /**
     * This fuzzy method takes two arguments.  The first arguement is the id of a tag
     * for which there is an event given by addAjaxUpdate.  The second argument is a javascript function to call.
     * Once the addAjaxUpdate request has been initiated this function is evaled.  Though to be honest, this
     * function may be evaled just before the request has been initiated -- mootools in none to clear on this detail.
     */
    public function addAjaxRequestFunction($obj,$id,$func) {
        $this->addAjaxFunction($obj,$id,$func,'request');
    }

  }

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