<?php

class MActionFlow
{

    public $action;
    public $form;
    public $flow;
    public $defaultFlow;
    public $decision;
    public $onEntry;
    public $onExit;

    function __construct($action, $form = '')
    {
        $this->action = $action;
        $this->form = $form;
    }

    function setForm($form)
    {
        $this->form = $form;
    }

    function getForm()
    {
        return $this->form;
    }

    function addFlow($flow, $targetAction)
    {
        if ($this->defaultFlow == '') $this->defaultFlow = $flow;
        $this->flow[$flow] = $targetAction;
    }

    function setDecision($decision)
    {
        $this->decision = $decision;
    }

    function getDecision()
    {
        return $this->decision;
    }

    function setOnEntry($entry)
    {
        $this->onEntry = $entry;
    }

    function getOnEntry()
    {
        return $this->onEntry;
    }

    function setOnExit($exit)
    {
        $this->onExit = $exit;
    }

    function getOnExit()
    {
        return $this->onExit;
    }

    function getTargetAction($flow)
    {
        $target = ($flow == '') ? $this->action : $this->flow[$flow];
        return ($target != '') ? $target : $flow;
    }


}


class MActionPanelFlow extends MActionPanelObject
{
    public  $actionNode;
    public $finalAction;
    public $flowData;
    public  $actionFlow;
    public $go;


    public function setInitialAction($action)
    {
        $initial = $this->actionNode[$action];
        $this->actionNode['initial'] = $initial;
        $this->addCommand('initial',$initial->form);
    }

    public function setFinalAction($action, $url)
    {
        $this->finalAction = $action;
        $this->actionNode[$action] = $url;
    }

    public function addAction($action, $form)
    {
        $a = new MActionFlow($action, $form);
        $this->actionNode[$action] = $a;
        $this->addCommand($action,$form);
        return $this->actionNode[$action];
    }

    public function getFlowData()
    {
        $this->flowData = $this->manager->getSession()->get('webflow_'.$this->id);
        return $this->flowData;
    }

    public function setFlowData()
    {
        $this->manager->getSession()->set('webflow_'.$this->id, $this->flowData);
    }

    public function initFlowData()
    {
        $this->manager->getSession()->set('webflow_'.$this->id, $this->flowData);
    }

    public function clearFlowData()
    {
        $this->manager->getSession()->unregister('webflow_'.$this->id);
    }

    public function initializeFlow()
    {
    }

    public function finalizeFlow()
    {
    }

    public function getURL($flow = '', $oid = '', $args = '')
    {
        return parent::getURL($this->actionFlow->getTargetAction($flow), $oid, $args);    
    }

    public function go($flow = '', $oid = '')
    {
        $this->go = $this->getURL($flow, $oid);
    }

    public function execute($action)
    {
        global $MIOLO;

        // verify if it is a valid execution (which means, the initial flow was executed)
        // if not, force initial flow
        $this->getFlowData();
        if ($this->flowData)
        {
            if ($this->flowData->__id != 'webflow_'.$this->id)
            {
                $action = '';
            }
        }
        else
        {
            $action = '';
        }

        if ($action == '')
        {
            $action = 'initial';
            $this->flowData = new MDataObject();
            $this->flowData->__id = 'webflow_'.$this->id;
            $this->initFlowData();
            $this->initializeFlow();
            $this->setFlowData();
        }

        if ($action == $this->finalAction)
        {
            $this->finalizeFlow();
            $this->clearFlowData();
            $this->go = $this->actionNode[$action];
        }
        else
        {
            $this->actionFlow = $this->actionNode[$action];
            $this->go = NULL;
            if ($this->flowData->__current != $this->actionFlow->action) // transition
            {

                if ($current = $this->flowData->__current)
                {
                    $exit = $this->actionNode[$current]->getOnExit();
                    if ($exit)
                    {
                       $this->$exit();
                    }
                }

                $this->flowData->__previous = $this->flowData->__current;
                $this->flowData->__current = $this->actionFlow->action;

                $entry = $this->actionNode[$this->actionFlow->action]->getOnEntry();
                if ($entry)
                {
                   $this->$entry();
                }
            }
   	        $form = $this->getUI()->getForm($this->module,$this->actionFlow->getForm(),$this,$this->formFolder);
            $form->setWidth('96%');
      		$form->setClose($this->manager->getActionURL($this->module, $this->action));
            $this->addControl($form);
            $this->setFlowData();
                
            if ($form->isSubmitted())
            {
                $decision = $this->actionFlow->getDecision();
                if ($decision)
                {
                    $this->$decision();
                }
                else if (!$this->go)
                {
                    $this->go = $this->getURL($this->actionFlow->defaultFlow);

                }
            }
        }
        if ($this->go)
        {
            $this->manager->getPage()->redirect($this->go);
        }
    }

    public function getXMLFlow($fileName, $params = NULL)
    {
        $file = "forms/" . $this->formFolder . "/" . $fileName;

        $path = $this->manager->getModulePath( $this->module, $file );

        if ( file_exists( $path ) )
        {
            if (is_null($params))
            {
                $params = new MDataObject();
            }
            $params->__flow = $this;
            $webflow = new MXMLFlow();
            $webflow->loadFile($path, $params);
            $actions = $webflow->get('actions');
            $initial = $webflow->get('initial');
            $final = $webflow->get('final');
            foreach($actions as $action)
            {
                $a = $this->addAction($action->action, $action->form);
                $a->setDecision($action->decision);
                foreach($action->flow as $f)
                {
                    $a->addFlow($f->flow, $f->target);
                }
            }
            $this->setInitialAction($initial[0]->action);
            $this->setFinalAction($final[0]->action, $final[0]->url);
        }

    }
}

?>