<?php

/**
 * This file defines the ProductSpec class
 *
 * @package CGProductBuilder
 * @category Products
 * @author  calguy1000 <calguy1000@cmsmadesimple.org>
 * @copyright Copyright 2010 by Robert Campbell
 */

namespace CGProductBuilder;

/**
 * An intermediate class that defines a product specification.
 * An instance of this class is passed to dispositions.
 * Dispositions can use this object to output the complete product specification in various formats.
 *
 * @package CGProductBuilder
 * @property int $returnid The id of the content page that created this productSpec
 * @property cgpb_productbuilder $content A reference to the actual content page that created this productspec <em>(read only)</em>
 * @property string $name The name of this product.
 * @property float $baseprice The base price of this product <em>(actual value may change for each occurrance depending upon FEU status)</em>
 * @property float $price The final price of this product including all selected options.
 * @property string $description The description for the product.  May include HTML.
 * @property optionsets[] $optionsets The optionsets associated with the product.
 * @property-read array $options An array of stdclass objects that define the selected options.   See the module help for a clear description of each member.
 * @property bool is_wholesale A boolean indicating that wholesale prices are in effect and used in calculations.
 */
class ProductSpec
{
    /**
     * @ignore
     */
    private $_content;

    /**
     * @ignore
     */
    private $_name;

    /**
     * @ignore
     */
    private $_description;

    /**
     * @ignore
     */
    private $_optionsets;

    /**
     * @ignore
     */
    private $_sel_options;

    /**
     * @ignore
     */
    private $_base_price;

    /**
     * @ignore
     */
    private $_final_price;

    /**
     * @ignore
     */
    private $_wholesale_flag;

    /**
     * Constructor
     *
     * @param cgpb_productbuilder $content The content page that contains the current state of the product build.
     */
    public function __construct($content = null)
    {
        if( $content && $content instanceof \cgpb_productbuilder ) {
            $this->build_from_content($content);
        }
    }

    /**
     * Build this object from a product builder page.
     *
     * @param cgpb_productbuilder The content page that contains the current state of the product build.
     */
    public function build_from_content(\cgpb_productbuilder $content)
    {
        $mod = \cms_utils::get_module(MOD_CGPRODUCTBUILDER);
        $this->_content = $content;
        $this->_name = $content->Name();
        $tpl = $content->Show('content_en');
        $tpl = preg_replace('/\{CGProductBuilder.*\}/','',$tpl);
        try {
            $this->_description = $mod->ProcessTemplateFromData($tpl); // problematic??
        }
        catch( \Exception $e ) {
            $this->_description = $tpl;
        }
        $this->_optionsets = $content->get_optionsets();
        $this->_sel_options = $content->get_all_selected_options();
        $this->_base_price = $content->get_retailprice();
        $wholesale = $mod->use_wholesale();
        if( $wholesale ) {
            $this->_base_price = $content->get_wholesaleprice();
            $this->_wholesale_flag = TRUE;
        }
        $this->_final_price = $content->get_current_price();
    }

    /**
     * @ignore
     */
    public function __get($key)
    {
        $key = trim((string) $key);
        switch( $key ) {
        case 'returnid':
        case 'pageid':
            return $this->_content->Id();

        case 'content':
            return $this->_content;

        case 'name':
            return trim($this->_name);

        case 'baseprice':
            return (float) $this->_base_price;

        case 'price':
            return (float) $this->_final_price;

        case 'description':
            return trim($this->_description);

        case 'optionsets':
            return $this->_optionsets;

        case 'options':
            return $this->_sel_options;

        case 'is_wholesale':
            return $this->wholesale_flag;

        default:
            throw new \CmsInvalidDataException("$key is not a valid member of ".__CLASS__);
        }
    }

    /**
     * @ignore
     */
    public function __set($key,$val)
    {
        $key = trim((string) $key);
        switch( $key ) {
        case 'content':
            if( !$val instanceof \cgpb_productbuilder ) throw new \CmsInvalidDataException("$val is an invalid value for $key in ".__CLASS__);
            break;

        case 'name':
            $val = trim($val);
            if( !$val ) throw new \CmsInvalidDataException("$val is an invalid value for $key in ".__CLASS__);
            $this->_name = $val;
            break;

        case 'baseprice':
            $val = (float) $val;
            if( $val < 0.00 ) throw new \CmsInvalidDataException("$val is an invalid value for $key in ".__CLASS__);
            $this->_base_price = $val;
            break;

        case 'price':
            $val = (float) $val;
            if( $val < 0.00 ) throw new \CmsInvalidDataException("$val is an invalid value for $key in ".__CLASS__);
            $this->_final_price = $val;
            break;

        case 'content':
        case 'description':
            $val = trim($val);
            $his->_description = $val;
            break;

        case 'optionsets':
            if( !is_array($val) ) throw new \CmsInvalidDataException("$val is an invalid value for $key in ".__CLASS__);
            foreach( $val as $rec ) {
                if( ! $rec instanceof option_set )  throw new \CmsInvalidDataException("$val is an invalid value for $key in ".__CLASS__);
            }
            $this->_optionsets = $val;
            break;

        case 'is_wholesale':
            $this->_wholesale_flag = \cge_utils::to_bool($val);
            break;

        case 'options':
            throw new \LogicException("$key is not a settable member of ".__CLASS__);
            /*
            if( !is_array($val) ) throw new \CmsInvalidDataException("$val is an invalid value for $key in ".__CLASS__);
            foreach( $val as $rec ) {
                if( ! $rec instanceof option )  throw new \CmsInvalidDataException("$val is an invalid value for $key in ".__CLASS__);
            }
            $this->_sel_options = $val;
            */
            break;

        default:
            throw new \LogicException("$key is not a valid member of ".__CLASS__);
        }
    }

    /*
    public function __isset($key)
    {

    }

    public function __unset($key)
    {

    }
    */

} // end of class

?>
