<?php

$MIOLO->page->addScript('GnutecaArrayField.js', 'gnuteca3');

class GnutecaArrayField extends MContainer
{
	private $controlNames; //nome dos controles escaneados na função parseFields
	private $_name;
	private $_controls, $module, $MIOLO;

	function __construct($name, $controls )
	{
		if (!is_array($controls))
		{
			$controls = array($controls);
		}
		$MIOLO    	 		= MIOLO::getInstance();
		$this->MIOLO        = $MIOLO;
		$this->_name        = $name;
		$this->_controls    = $controls;
		$this->module       = MIOLO::_REQUEST("module");
		$controls 	 		= $this->parseFields($controls, $index);
		$container[] 		= $this->convertControl($controls); //joga os campos dentro de um container
		$container[]        = new MHiddenField( $name.'_counter', '0'); //adiciona contador
		parent::__construct($name, $container, 'vertical', MFormControl::FORM_MODE_SHOW_NBSP);

		$this->page->onload('gnutecaArrayField.parseLookup(\''.$name.'\');');
	}

	/**
	 * Retorna um container com os campos
	 *
	 * @param unknown_type $controls
	 * @param unknown_type $addButton
	 * @return unknown
	 */
	private function convertControl( $controls, $nFields = 0, $index = 0)
	{
		$MIOLO    	 = MIOLO::getInstance();

        $addUrl       = $this->MIOLO->getUI()->getImage($this->module,'add-16x16.png');
        $addImg      = new MImageButton("{$this->_name}_{$index}_add", '&nbsp;', "gnutecaArrayField.add('{$index}', '{$this->_name}');", $addUrl);

        $delUrl      = $this->MIOLO->getUI()->getImage($this->module,'delete-16x16.png');
		$delImg      = new MImageButton("{$this->_name}_{$index}_remove", '&nbsp;', "gnutecaArrayField.remove('{$this->_name}_{$index}_container', '{$this->_name}');", $delUrl);

        if ( $index != ($nFields - 1) )
        {
            $addImg->addStyle('visibility', 'hidden'); //esconde del
        }

        $controls    = array_merge (is_array($controls ) ? $controls : array($controls) , array($delImg), array($addImg) ); //array_merge precisa que todos seja array

		return new MHContainer($this->_name.'_'. $index .'_container', $controls);
	}

	/**
	 * Trabalha os campos internos do gnutecaArrayField,
	 * registrando um array com o nome dos campos a tratar no get data,
	 * assim como, tratando os id dos campos adicionando [] neles para que os dados sejam pegos corretamento no final
	 *
	 * @param Object $field o campo ou array de campos
	 * @param Object $data dados a serem forçados no campo
	 * @return Object
	 */
	private function parseFields($field, $data, $index = 0)
	{
		if ( is_array( $field ) )
        {
            foreach ($field as $line => $info )
            {
                $field[$line] = $this->parseFields( $info, $data, $index );
            }
            return $field;
        }

        if ( $field instanceof MLookupTextField )
        {
            $newField  = clone($field); //clona para pode aceitar vários
            $currentName         = $newField->name;
            $newField->id       .= "[$index]";
            $newField->name     .= "[$index]";
            $currentRelated      = explode(",", $newField->related);
            $newField->related   = '';
            foreach ($currentRelated as $fieldX)
            {
                $newField->related .= $fieldX ."[$index],";
            }
            $newField->related = substr($newField->related, 0, -1);

            $this->MIOLO->page->addJsCode("{$newField->lookup_name} = new Array;");

            /*
        	$this->controlNames[] = $field->name;

            if ($data)
        	{
        		$fieldName = str_replace('_container', '' , $newField->name);
        		$newField->setValue($data->$fieldName);
        	}

            $controls   = $newField->getControls();
            $child      = clone( $controls[1] );

            if ( $child->name )
			{
			    $child->name 	.='['.$index.']';
			}

			if ( $child->id )
        	{
        		$child->id 	.='['.$index.']';
        	}

        	$newField->setControl( $child, 1);


            $controls   = $newField->getControls();
            $childDesc  = clone( $controls[2] );

            if ( $childDesc->name )
			{
			    $childDesc->name 	.='['.$index.']';
			}

			if ( $childDesc->id )
        	{
        		$childDesc->id 	.='['.$index.']';
        	}

        	$newField->setControl( $childDesc, 2);*/

            return $newField;
        }

        if ( ($field instanceof MContainer) )
        {
            $field->setControls( $this->parseFields( $field->getControls(), $data , $index ) );
            return $field;
        }

        if ( ($field instanceof MDiv)  )
        {
            $field->setInner( $this->parseFields( $field->getInner(), $data , $index ) );
            return $field;
        }

        if ($field->name)
        {
        	$newField  = clone($field); //clona para pode aceitar vários

        	$this->controlNames[] = $field->name;

        	if ( $newField->name )
			{
			    $newField->name 	.='['.$index.']';
			}

			if ( $newField->id )
        	{
        		$newField->id 	.='['.$index.']';
        	}

			if ($data)
        	{
        		$fieldName = str_replace('['.$index.']', '' , $newField->name);
        		$newField->setValue($data->$fieldName);
        	}

			return $newField;
        }
	}

	function setData( $data )
	{
		$this->setControls(null);

		$addButton = true;

		if (is_array($data))
		{
			if ( is_object( $data[0] ))
			{
				foreach ( $data as $line => $obj)
				{
					$controls  = $this->parseFields( $this->_controls , $obj, $line);
					$this->addControl( $this->convertControl( $controls, count($data), $line) );
					$index     = $line;
				}
			}
			else
			{
				foreach ( $data as $line => $array ) //dados
				{
					$i = 0;
					$controls = $this->parseFields( $this->_controls, null, $line);

					if ( is_array( $array ) )
					{
						foreach ( $array as $l => $i )
						{
							if (is_object( $controls[$l] ) )
							{
								if ( method_exists( $controls[$l] , 'setValue' ) )
								{
									$controls[$l]->setValue( $i );
								}
							}
						}
					}

					$this->addControl( $this->convertControl( $controls, count($data), $line) );
					$index = $line;
				}

    		}

			$this->addControl(  new MHiddenField( $this->name.'_counter', $index ? $index : '0') );
		}
		else
		{
			$controls = $this->parseFields( $this->_controls , $obj);
			$this->addControl( $this->convertControl( $controls, $addButton ) );
            $this->addControl(  new MHiddenField( $this->name.'_counter', $index ? $index : '0') );
		}
	}


	/**
	 * Retorna um array de objetos, onde cada linha é um registro do ArrayField
	 *
	 * @return Array de objetos
	 */
	function getData()
	{
		$data 			= (Object) $_REQUEST;
		$controlData 	= null;

		//separa só os dados necessários
		if (is_array($this->controlNames))
		{
			foreach ( $this->controlNames as $line => $info)
			{
				$controlData[$info] = $data->$info;
			}
		}

		//retorna no formato adequado
		if (is_array($controlData))
		{
			foreach ($controlData as $indice => $dado)
			{
				if (is_array($dado))
				{
					foreach ( $dado as $line => $info)
					{
						$resultData[$line]->$indice = $info;
					}
				}
			}
		}

		return $resultData;
	}
}

/*
Example:


        //$controls2[]= new MSelection('testar2', null, _M('Testar2', $module) );
		$controls2[]= new MTextField('codigoA',null,  _M('CodigoA', $module) );
		//$controls2[]= new MTextField('codigoB',null,  _M('CodigoB', $module) );
        $loanIdS = new MLookupTextField('personId', 'teste', 'testes', FIELD_LOOKUPFIELD_SIZE);
        $loanIdS->setContext($this->module, $this->module, 'Person', 'filler', 'loanIdS,codigoA');
        $loanIdS->baseModule = $this->module;
        $controls2[] = $loanIdS;


        $arrayField2= new GnutecaArrayField('exemplo2', $controls2 );

		$obj1->testar2 = '1';
		$obj1->codigoA = 'Algum teste';
		$obj1->codigoB = 'Outro teste';
		$obj1->workflow= '89';
		$arrayField2Data[] = $obj1;

		$obj2->testar2 = '0';
		$obj2->codigoA = 'Algum teste 2';
		$obj2->codigoB = 'Outro teste 2';
		$arrayField2Data[] = $obj2;

		$obj3->testar2 = '0';
		$obj3->codigoA = 'Algum teste 3';
		$obj3->codigoB = 'Outro teste 3';
		$obj1->workflow= '89';
		$arrayField2Data[] = $obj3;

		$arrayField2->setData($arrayField2Data);

        $fields[]   = new MBaseGroup( null, 'Dados Exemplo', array( $arrayField2 ) );



*/

?>
