<?php

namespace Velis\Bpm\Company;

use Velis\Model\DataObject;
use Velis\Lang;
use Velis\Filter;
use Company\Company;

/**
 * Base for customer/partner address models
 * @author Olek Procki <olo@velis.pl>
 */
class Address extends DataObject
{

    /**
     * @var bool
     */
    private static $_forceZip = false;


    /**
     * Returns SQL table name
     * @return string
     */
    protected function _getTableName()
    {
        return 'app.company_address_tab';
    }


    /**
     * Returns primary key fields
     * @return array
     */
    protected function _getPrimaryKeyField()
    {
        return array('company_id', 'address_no');
    }


    /**
     * Returns company id
     * @return int
     */
    public function getCompanyId()
    {
        return $this->company_id;
    }


    /**
     * Returns company object
     * @return \Velis\Bpm\Company\Company
     */
    public function getCompany()
    {
        return new Company($this->company_id);
    }


    /**
     * Returns address zip code
     * @return string
     */
    public function getZipCode()
    {
        return $this['zip_code'];
    }


    /**
     * Returns address as string
     * @return string
     */
    public function __toString()
    {
        $address = '';

        if ($this['street_address']) {
            $address .= $this['street_address'];
        } else {
            $address .= $this['name'];
        }
        if ($this['zip_code'] || $this['city']) {
            $address .= "\n" . trim($this['zip_code'] . ' ' . $this['city']);
        }
        if ($this['city'] != $this['post_office'] && strlen($this['post_office'])) {
            $address .= ' (' . $this['post_office'] . ')';
        }
        return $address;
    }


    /**
     * Validate zipcode
     * @return Address
     *
     * @throws \InvalidArgumentException when zipcode invalid
     */
    public function validateZipCode()
    {
        if ($this->getZipCode() || !self::$_forceZip) {
            if (!Filter::filterZipCode($this->getZipCode())) {
                throw new \InvalidArgumentException(Lang::get('CUSTOMER_WRONG_ZIP_CODE'));
            }
        }
        return $this;
    }


    /**
     * Inserts new address
     *
     * @param bool $updateObjectId
     * @return Velis\Bpm\Company\Address
     */
    public function add($updateObjectId = false)
    {
        $referenceField = reset($this->_getPrimaryKeyField());

        $this['address_no'] = '(SELECT COALESCE(MAX(address_no)+1,1) FROM ' . $this->_getTableName() . ' WHERE ' . $referenceField . '=:' . $referenceField . ')';
        self::$_db->insert($this->_getTableName(), $this, array('address_no'));

        unset($this['address_no']);

        return $this;
    }


    /**
     * Save (add/modify)
     *
     * @param bool $updateObjectId
     * @return Address
     */
    public function save($updateObjectId = false)
    {
        if ($this['address_no']) {
            $this->modify();
        } else {
            $this->add();
        }
        return $this;
    }


    /**
     * Checks whether adress is of correspondence type
     *
     * @return bool
     */
    public function isCorrespondenceAddress()
    {
        return $this['is_correspondence_address'] == 1;
    }


    /**
     * Checks whether adress is of invoice type
     *
     * @return bool
     */
    public function isInvoiceAddress()
    {
        return $this['is_invoice_address'] == 1;
    }

    /**
     * Return address number
     *
     * @return int
     */
    public function getAddressNo()
    {
        return $this['address_no'];
    }


    /**
     * Return address name
     *
     * @return string
     */
    public function getName()
    {
        return $this['name'];
    }


    /**
     * Removes address
     */
    public function remove()
    {
        return parent::_remove();
    }


    /**
     * Force zip for local addresses
     * @param bool $force
     */
    public static function setForceZip($force)
    {
        self::$_forceZip = $force;
    }
}
