<?php

/**
 * Goweb Sitemanager 5 Framework
 * 
 * @version    5.0.0
 * @category   Goweb
 * @package    Goweb_Db
 * @subpackage Model
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2009 (c) Goweb (http://www.goweb.pt)
 */

/**
 * Classe que representa os dados de uma linha numa tabela.
 *
 * @version    5.0.0
 * @category   Goweb
 * @package    Goweb_Db
 * @subpackage Model
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2009 (c) Goweb (http://www.goweb.pt)
 */
class Goweb_Db_Model_Row {
    
    /**
     * Array com a lista de coluna da tabela.
     *
     * @var  array
     */
    protected $_cols = array();

    /**
     * Nome do model associado
     *
     * @var  array
     */
    protected $_modelName = '';

    /**
     * Model associado
     *
     * @var  array
     */
    protected $_model = null;
    
    /**
     * Nome do campo a para ser retornado o seu valor quando for devolvido o objecto.
     *
     * @var  string
     */
    protected $_toString = '';

    /**
     * Constructor
     */
    public function __construct($col = '') {
        $this->_toString = $col;
    }

    /**
     * Atribui os dados atraves de um array na forma: coluna => valor.
     *
     * @param  array  $array  Array com dos valores
     */
    public function setFromArray($array) {
        if (!is_array($array)) {
            throw new Goweb_Exception('O paremetro passado em "Goweb_Db_Model_Row::setFromArray()" n&atilde;o e do tipo array.');
        }
        $this->_cols = $array;
    }

    /**
     * Retorna os dados em formato array.
     *
     * @return  array  Os dados do model em formato array
     */
    public function toArray() {
        $row = array();
        foreach ($this->_cols as $key => $value) {
            $row[$key] = ($value instanceof Goweb_Db_Model_Row) ? $value->toArray() : $value;
        }
        return $row;
    }

    /**
     * Retorna um array com os nome das colunas da tabela.
     *
     * @return  array  Os dados do model em formato array
     */
    public function getCols() {
        return array_keys($this->_cols);
    }

    /**
     * Retorna se a coluna existe.
     *
     * @return  bool  TRUE se a coluna existir
     */
    public function colExists($col) {
        return array_key_exists($col, $this->_cols);
    }

    /**
     * Atribui o nome da coluna a retornar o seu valor no __toString().
     *
     * @param   string  $col  Nome da coluna
     */
    public function setToString($col) {
        $this->_toString = $col;
    }

    /**
     * Atribui o nome do model associado.
     *
     * @param   string  $col  Nome do model
     */
    public function setModelName($modelName) {
        $this->_modelName = $modelName;
    }

    /**
     * Retorna o objecto do model associado.
     *
     * @retirn  Goweb_Db_Model  O objecto do model associado
     */
    public function getModel() {
        if (!$this->_model instanceof Goweb_Db_Model) {
            $this->_model = Goweb::getModelInstance($this->_modelName());
            $this->_model->find($this->_cols[$this->_model->getPrimary()]);
        }
        return $this->_model;
    }

    /**
     * Limpa os dados da row.
     */
    public function reset() {
        foreach (array_keys($this->_cols) as $col) {
            // e uma ForeignKey?
            if ($this->_cols[$col] instanceof Goweb_Db_Model_Row) {
                $this->_cols[$col]->reset();
            } else {
                $this->_cols[$col] = null;
            }
        }        
    }
    
    /**
     * Retorna o valor de uma coluna.
     *
     * @param   string  $col     Nome da coluna
     * @throws  Goweb_Exception  Caso a coluna n&atilde;o exista
     * @return  string           O valor da coluna
     */
    public function __get($col) {
        if (array_key_exists($col, $this->_cols)) {
            return $this->_cols[$col];
        }
        throw new Goweb_Exception('A coluna "' . $col . '" n&atilde;o existe no objecto "Goweb_Db_Model_Row".');
    }

    /**
     * Atribui o valor a uma coluna
     *
     * @param   string  $col    Nome da coluna
     * @param   string  $value  Valor a ser atribuido
     */
    public function __set($col, $value) {
        $this->_cols[$col] = $value;
    }

    /**
     * Retorna o valor do campo do model atribuido em Goweb_Db_Model_Row::_toString, quando
     * mostrado o objecto.
     *
     * @return  string  Valor do campo atribuido em Goweb_Db_Model::_toString
     */    
    public function __toString() {
        if (strlen($this->_toString)) {
            return (string) $this->_cols[$this->_toString];
        }
        return '';        
    }

    /**
     * Unset row field value
     *
     * @param  string $columnName The column key.
     */
    public function __unset($columnName)
    {
        unset($this->_cols[$columnName]);
    }
}
