<?php
namespace concourse\thrift\complex;

/**
* Autogenerated by Thrift Compiler (0.9.3)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
*  @generated
*/
use Thrift\Base\TBase;
use Thrift\Type\TType;
use Thrift\Type\TMessageType;
use Thrift\Exception\TException;
use Thrift\Exception\TProtocolException;
use Thrift\Protocol\TProtocol;
use Thrift\Protocol\TBinaryProtocolAccelerated;
use Thrift\Exception\TApplicationException;
use Concourse\Convert;


/**
* The possible types for a {@link ComplexTObject}.
*/
final class ComplexTObjectType {
    const SCALAR = 1;
    const MAP = 2;
    const TLIST = 3;
    const SET = 4;
    const TOBJECT = 5;
    const TCRITERIA = 6;
    static public $__names = array(
        1 => 'SCALAR',
        2 => 'MAP',
        3 => 'TLIST',
        4 => 'SET',
        5 => 'TOBJECT',
        6 => 'TCRITERIA'
    );
}

/**
* A recursive structure that encodes one or more {@link TObject TObjects}.
*
* <p>
* The most basic {@link ComplexTObject} is a
* {@link ComplexTObjectType#SCALAR scalar}, which is just a wrapped
* {@link TObject}. Beyond that, complex collections can be represented as a
* {@link Set}, {@link List} or {@link Map} of
* {@link ComplexTObject ComplexTObjects}.
* </p>
*/
class ComplexTObject {

    /**
     * [fromPhpObject description]
     * @param  [type] $obj [description]
     * @return [type]      [description]
     */
    public static function fromPhpObject($obj){
        $complex = new ComplexTObject();
        if(is_assoc_array($obj)){
            $complex->type = ComplexTObjectType::MAP;
            $tmap = array();
            foreach($obj as $key => $value){
                $tmap[static::fromPhphObject($key)] = static::fromPhpObject($value);
            }
            $complex->tmap = $tmap;
        }
        else if(is_array($obj)){
            $complex->type = ComplexTObjectType::TLIST;
            $tlist = array();
            foreach($obj as $elt){
                $tlist[] = static::fromPhpObject($elt);
            }
            $complex->tlist = $tlist;
        }
        else {
            $complex->type = ComplexTObjectType::SCALAR;
            $complex->tscalar = Convert::phpToThrift($obj);
        }
        return $complex;
    }

    static $_TSPEC;

    /**
    * @var int
    */
    public $type = null;
    /**
    * @var \concourse\thrift\data\TObject
    */
    public $tscalar = null;
    /**
    * @var array
    */
    public $tmap = null;
    /**
    * @var \concourse\thrift\complex\ComplexTObject[]
    */
    public $tlist = null;
    /**
    * @var \concourse\thrift\complex\ComplexTObject[]
    */
    public $tset = null;

    public function __construct($vals=null) {
        if (!isset(self::$_TSPEC)) {
            self::$_TSPEC = array(
                1 => array(
                    'var' => 'type',
                    'type' => TType::I32,
                ),
                2 => array(
                    'var' => 'tscalar',
                    'type' => TType::STRUCT,
                    'class' => '\concourse\thrift\data\TObject',
                ),
                3 => array(
                    'var' => 'tmap',
                    'type' => TType::MAP,
                    'ktype' => TType::STRUCT,
                    'vtype' => TType::STRUCT,
                    'key' => array(
                        'type' => TType::STRUCT,
                        'class' => '\concourse\thrift\complex\ComplexTObject',
                    ),
                    'val' => array(
                        'type' => TType::STRUCT,
                        'class' => '\concourse\thrift\complex\ComplexTObject',
                    ),
                ),
                4 => array(
                    'var' => 'tlist',
                    'type' => TType::LST,
                    'etype' => TType::STRUCT,
                    'elem' => array(
                        'type' => TType::STRUCT,
                        'class' => '\concourse\thrift\complex\ComplexTObject',
                    ),
                ),
                5 => array(
                    'var' => 'tset',
                    'type' => TType::SET,
                    'etype' => TType::STRUCT,
                    'elem' => array(
                        'type' => TType::STRUCT,
                        'class' => '\concourse\thrift\complex\ComplexTObject',
                    ),
                ),
            );
        }
        if (is_array($vals)) {
            if (isset($vals['type'])) {
                $this->type = $vals['type'];
            }
            if (isset($vals['tscalar'])) {
                $this->tscalar = $vals['tscalar'];
            }
            if (isset($vals['tmap'])) {
                $this->tmap = $vals['tmap'];
            }
            if (isset($vals['tlist'])) {
                $this->tlist = $vals['tlist'];
            }
            if (isset($vals['tset'])) {
                $this->tset = $vals['tset'];
            }
        }
    }

    public function getName() {
        return 'ComplexTObject';
    }

    public function read($input)
    {
        $xfer = 0;
        $fname = null;
        $ftype = 0;
        $fid = 0;
        $xfer += $input->readStructBegin($fname);
        while (true)
        {
            $xfer += $input->readFieldBegin($fname, $ftype, $fid);
            if ($ftype == TType::STOP) {
                break;
            }
            switch ($fid)
            {
                case 1:
                if ($ftype == TType::I32) {
                    $xfer += $input->readI32($this->type);
                } else {
                    $xfer += $input->skip($ftype);
                }
                break;
                case 2:
                if ($ftype == TType::STRUCT) {
                    $this->tscalar = new \concourse\thrift\data\TObject();
                    $xfer += $this->tscalar->read($input);
                } else {
                    $xfer += $input->skip($ftype);
                }
                break;
                case 3:
                if ($ftype == TType::MAP) {
                    $this->tmap = array();
                    $_size0 = 0;
                    $_ktype1 = 0;
                    $_vtype2 = 0;
                    $xfer += $input->readMapBegin($_ktype1, $_vtype2, $_size0);
                    for ($_i4 = 0; $_i4 < $_size0; ++$_i4)
                    {
                        $key5 = new \concourse\thrift\complex\ComplexTObject();
                        $val6 = new \concourse\thrift\complex\ComplexTObject();
                        $key5 = new \concourse\thrift\complex\ComplexTObject();
                        $xfer += $key5->read($input);
                        $val6 = new \concourse\thrift\complex\ComplexTObject();
                        $xfer += $val6->read($input);
                        $this->tmap[$key5] = $val6;
                    }
                    $xfer += $input->readMapEnd();
                } else {
                    $xfer += $input->skip($ftype);
                }
                break;
                case 4:
                if ($ftype == TType::LST) {
                    $this->tlist = array();
                    $_size7 = 0;
                    $_etype10 = 0;
                    $xfer += $input->readListBegin($_etype10, $_size7);
                    for ($_i11 = 0; $_i11 < $_size7; ++$_i11)
                    {
                        $elem12 = null;
                        $elem12 = new \concourse\thrift\complex\ComplexTObject();
                        $xfer += $elem12->read($input);
                        $this->tlist []= $elem12;
                    }
                    $xfer += $input->readListEnd();
                } else {
                    $xfer += $input->skip($ftype);
                }
                break;
                case 5:
                if ($ftype == TType::SET) {
                    $this->tset = array();
                    $_size13 = 0;
                    $_etype16 = 0;
                    $xfer += $input->readSetBegin($_etype16, $_size13);
                    for ($_i17 = 0; $_i17 < $_size13; ++$_i17)
                    {
                        $elem18 = null;
                        $elem18 = new \concourse\thrift\complex\ComplexTObject();
                        $xfer += $elem18->read($input);
                        if (is_scalar($elem18)) {
                            $this->tset[$elem18] = true;
                        } else {
                            $this->tset []= $elem18;
                        }
                    }
                    $xfer += $input->readSetEnd();
                } else {
                    $xfer += $input->skip($ftype);
                }
                break;
                default:
                $xfer += $input->skip($ftype);
                break;
            }
            $xfer += $input->readFieldEnd();
        }
        $xfer += $input->readStructEnd();
        return $xfer;
    }

    public function write($output) {
        $xfer = 0;
        $xfer += $output->writeStructBegin('ComplexTObject');
        if ($this->type !== null) {
            $xfer += $output->writeFieldBegin('type', TType::I32, 1);
            $xfer += $output->writeI32($this->type);
            $xfer += $output->writeFieldEnd();
        }
        if ($this->tscalar !== null) {
            if (!is_object($this->tscalar)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('tscalar', TType::STRUCT, 2);
            $xfer += $this->tscalar->write($output);
            $xfer += $output->writeFieldEnd();
        }
        if ($this->tmap !== null) {
            if (!is_array($this->tmap)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('tmap', TType::MAP, 3);
            {
                $output->writeMapBegin(TType::STRUCT, TType::STRUCT, count($this->tmap));
                {
                    foreach ($this->tmap as $kiter19 => $viter20)
                    {
                        $xfer += $kiter19->write($output);
                        $xfer += $viter20->write($output);
                    }
                }
                $output->writeMapEnd();
            }
            $xfer += $output->writeFieldEnd();
        }
        if ($this->tlist !== null) {
            if (!is_array($this->tlist)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('tlist', TType::LST, 4);
            {
                $output->writeListBegin(TType::STRUCT, count($this->tlist));
                {
                    foreach ($this->tlist as $iter21)
                    {
                        $xfer += $iter21->write($output);
                    }
                }
                $output->writeListEnd();
            }
            $xfer += $output->writeFieldEnd();
        }
        if ($this->tset !== null) {
            if (!is_array($this->tset)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('tset', TType::SET, 5);
            {
                $output->writeSetBegin(TType::STRUCT, count($this->tset));
                {
                    foreach ($this->tset as $iter22 => $iter23)
                    {
                        if (is_scalar($iter23)) {
                            $xfer += $iter22->write($output);
                        } else {
                            $xfer += $iter23->write($output);
                        }
                    }
                }
                $output->writeSetEnd();
            }
            $xfer += $output->writeFieldEnd();
        }
        $xfer += $output->writeFieldStop();
        $xfer += $output->writeStructEnd();
        return $xfer;
    }

    /**
     * [getPhpObject description]
     * @return [type] [description]
     */
    public function getPhpObject(){
        if($this->type == ComplexTObjectType::MAP){
            $ret = array();
            foreach($this->tmap as $key => $value) {
                $ret[$key->getPhpObject()] = $value->getPhpObject();
            }
        }
        else if($this->type == ComplexTObjectType::TLIST || $this->type == ComplexTObjectType::SET) {
            $ret = array();
            $coll = $this->tlist ?: $this->tset;
            foreach($coll as $item){
                $ret[] = $item->getPhpObject();
            }
        }
        else {
            $ret = Convert::thriftToPhp($this->tscalar);
        }
        return $ret;
    }

}
