<?php

/**
 * The definition for the contact class.
 *
 * @package CGContacts
 * @category Productivity
 * @author  calguy1000 <calguy1000@cmsmadesimple.org>
 * @copyright Copyright 2014 by Robert Campbell
 */

namespace CGContacts;

/**
 * An abstract class to describe a basic object.
 * A contact can consist of multiple objects of different types.
 */
abstract class contact_sub
{
    /**
     * @ignore
     */
    private $_contact;

    /**
     * @ignore
     */
    private $_data = array();

    /**
     * Constructor
     *
     * @param contact $parent A reference to the contact object that will own this object.
     */
    public function __construct(contact &$parent) {
        $this->_contact = $parent;
    }

    /**
     * Return the id of the parent contact object.
     * If the contact object is new and has not been saved, it may not have an id.
     *
     * @return int
     */
    public function get_contact_id()
    {
        $id = \cge_utils::get_param($this->_data,'contact_id');
        if( !$id ) return $this->_parent->get_id();
    }

    /**
     * Get the class (type) of this object.
     *
     * @return string
     */
    public function get_class() {
        $class = get_class($this);
        $class = str_replace('\\','/',$class);
        return basename($class);
    }

    /**
     * Get the label, if any, associated with this object.
     *
     * @return string
     */
    public function get_label()
    {
        return \cge_utils::get_param($this->_data,'label');
    }

    /**
     * Set a label for this object.
     *
     * @param string $label
     */
    public function set_label($label)
    {
        $label = trim($label);
        if( !$label ) throw new \CmsInvalidDataException('label cannot be empty in a '.$this->get_class().' object');
        $this->_data['label'] = trim((string)$label);
    }

    /**
     * Test if this object is a preferred object of its type for this contact.
     *
     * @return bool
     */
    public function is_preferred()
    {
        return (bool) \cge_utils::get_param($this->_data,'preferred');
    }

    /**
     * Set the preferred flag for this object.
     *
     * This method will attempt to interpret the passed value as a boolean in any way it can.
     *
     * @param mixed $flag
     */
    public function set_preferred($flag = TRUE)
    {
        $flag = (bool) \cge_utils::to_bool($flag);
        $this->_data['preferred'] = $flag;
    }

    /**
     * Whether there can be multiple objects of this type associated with a contact.
     *
     * @abstract
     * @return bool
     */
    public function allows_multiple()
    {
        return TRUE;
    }

    /**
     * Validate the contents of the object.  Throw an exception if an error is encountered.
     *
     * @abstract
     */
    public function validate()
    {
        if( $this->get_class() == '' ) throw new \CmsInvalidDataException('Each contact object must have a class');
        if( $this->get_label() == '' ) throw new \CmsInvalidDataException('Each contact object must have a label');
    }

    /**
     * Get the raw value (for storing in the database) of this object.
     *
     * @return string
     */
    abstract public function get_raw_value();

    /**
     * Convert this object to a data array.
     *
     * @abstract
     * @return array
     */
    public function to_data()
    {
        $out = $this->_data;
        $out['class'] = $this->get_class();
        return $out;
    }

    /**
     * Fill this object from a data array.
     *
     * @abstact
     * @param array $data
     */
    public function set_data($data)
    {
        // validate ths data
        $contact_id = (int)\cge_utils::get_param($data,'contact_id');
        $label = trim(\cge_utils::get_param($data,'label'));
        $preferred = \cge_utils::to_bool(\cge_utils::get_param($data,'preferred'));
        if( $label == '') throw new \CmsInvalidDataException('data supplied to '.__METHOD__.' is invalid');

        if( $contact_id > 0 )  $this->_data['contact_id'] = $contact_id;
        $this->_data['label'] = $label;
        $this->_data['preferred'] = $preferred;
    }
} // end of class

?>
