<?php

/**
 * This file defines the TicketListQuery class.
 *
 * @package CGClientTickets
 * @category Application
 * @author  calguy1000 <calguy1000@cmsmadesimple.org>
 * @copyright Copyright 2010 by Robert Campbell
 */

namespace CGClientTickets\Repository;

/**
 * This class generates a ticket list based on various criteria.
 *
 * It is used for the tickets tab in the admin interface, and possibly the
 * frontend user ticket list interface.
 *
 * @property int $owner Query tickets with the specified owner.  A positive integer is expected, representing an FEU uid.
 * @property int[]|int $alert_group Query tickets with the specified alert group or groups. Either an array of integers, or an integer.  Values must be negative integers representing
 *    CMSMS admin group ids.
 * @property string $unread_by Query tickets that have messages that are unread by somebody.  Possible values are:<br/>
 *     self::UNREADBY_ANY - Unread by anybody<br/>
 *     self::UNREADBY_ADMIN - Unread by an admin<br/>
 *     self::UNREADBY_OWNER - Unread by the ticket owner.
 * @property string $e_key1 Query tickets with the specified e_key1 value.
 * @property string $e_key2 Query tickets with the specified e_key2 value.  Note, the e_key1 value must also be specified.
 * @property string $e_key3 Query tickets with the specified e_key3 value.  Note, the e_key2 value must also be specified.
 * @property string $status Query tickets with the specified status.  Possible values are:<br/>
 *     ticket::STATUS_OPEN<br/>
 *     ticket::STATUS_CLOSED<br/>
 *     ticket::STATUS_EXPIRED
 * @property string $priority Query tickets with the specified priority.  Possible values are:<br/>
 *     ticket::PRIORITY_HIGH<br/>
 *     ticket::PRIORITY_NORMAL<br/>
 *     ticket::PRIORITY_LOW
 * @property int $limit The maximum number of records to return in one resultset.
 * @property int $offset The start offset of records to return.
 */
class TicketListQuery extends \CGExtensions\query\query
{
    /**
     * @ignore
     */
    private $_data;
    const UNREADBY_ANY = 'any';
    const UNREADBY_ADMIN = 'admin';
    const UNREADBY_OWNER = 'owner';

    /**
     * Constructor
     *
     * @param array $parms An associative array of the initial properties for this object.
     */
    public function __construct($parms = array()) {
        // @todo: check the params
        foreach( $parms as $key => $val ) {
            $this[$key] = $val;
        }
    }

    /**
     * @ignore
     */
    public function OffsetGet($key)
    {
        switch( $key ) {
        case 'owner':
        case 'unread_by':
        case 'alert_group':
        case 'status':
        case 'e_key1':
        case 'e_key2':
        case 'e_key3':
        case 'priority':
            if( isset($this->_data[$key]) ) return $this->_data[$key];
            break;

        case 'limit':
            if( isset($this->_data[$key]) ) return (int) $this->_data[$key];
            return 100;

        case 'offset':
            if( isset($this->_data[$key]) ) return (int) $this->_data[$key];
            return 0;

        default:
            throw new \RuntimeException($key.' is an invalid parameter for a '.__CLASS__);
        }
    }

    /**
     * @ignore
     */
    public function OffsetSet($key,$value)
    {
        switch( $key ) {
        case 'owner':
            // has to be a positive integer
            $n_value = (int) $value;
            if( $n_value < 1 ) {
                unset($this->_data['owner']);
            }
            else {
                $this->_data[$key] = $n_value;
            }
            unset($this->_data['alert_group']);
            break;

        case 'alert_group':
            // has to be a negative integer
            if( is_array($value) ) {
                $n_value = array();
                foreach( $value as $one ) {
                    $one = (int) $one;
                    if( $one >= 0 ) throw new \RuntimeException("$n_value is an invalid alert group for ".__CLASS__);
                    $n_value[] = $one;
                }
                $n_value = array_unique($n_value);
                if( count($n_value) == 1 ) $n_value = $n_value[0];
            }
            else {
                $n_value = (int) $value;
                if( $n_value >= 0 ) throw new \RuntimeException("$n_value is an invalid alert group for ".__CLASS__);
            }
            $this->_data[$key] = $n_value;
            unset($this->_data['owner']);
            break;

        case 'unread_by':
            switch( $value ) {
            case self::UNREADBY_ANY:
            case self::UNREADBY_OWNER:
            case self::UNREADBY_ADMIN:
                $this->_data[$key] = $value;
                break;

            default:
                throw new \RuntimeException("$value is an invalid unreadby status for ".__CLASS__);
            }
            break;

        case 'e_key1':
        case 'e_key2':
        case 'e_key3':
        case 'status':
        case 'priority':
            $value = trim($value);
            $this->_data[$key] = $value;
            break;

        case 'limit':
            $value = (int) $value;
            $value = max(1,min(1000,$value));
            $this->_data[$key] = $value;
            break;

        case 'offset':
            $value = (int) $value;
            $value = max(0,$value);
            $this->_data[$key] = $value;
            break;

        default:
            throw new \RuntimeException($key.' is an invalid parameter for a '.__CLASS__);
        }
    }

    /**
     * @ignore
     */
    public function OffsetExists($key)
    {
        switch( $key ) {
        case 'owner':
        case 'alert_group':
        case 'e_key1':
        case 'e_key2':
        case 'e_key3':
        case 'limit':
        case 'offset':
        case 'status':
        case 'priority':
        case 'unread_by':
            return isset($this->_data[$key]);

        default:
            throw new \RuntimeException($key.' is an invalid parameter for a '.__CLASS__);
        }
    }

    /**
     * Execute this query and generate a resultset.
     *
     * @return TicketListResultset
     */
    public function &execute()
    {
        $obj = new TicketListResultset($this);
        return $obj;
    }
} // end of class
