<?php

define("SERVER_MSG_HEADER_SIZE", 128);

class MsgDataType {
	const Text = 0;
	const Binary = 1;
};

class MsgProcessType {
	const Command = 0;
	const Response = 1;
	const Event = 2;
};


class TcpMsg {
	
	public $binaryData = NULL;
	public $binaryDataSize = 0;
	
	public $msgItems = array();
	public $processType = MsgProcessType::Event;
	public $dataType = MsgDataType::Text;
	public $component;
	public $name;
	

	private function readFromSocket($socket, $length) {
		
		$buffer = "";
                $red = 0;

		do {
                        $data = socket_read($socket, $length-$red);
                        if ($data === FALSE) {
                               $buffer = FALSE;
				break;
                        }

                        $buffer .= $data;
                        $red = $red + strlen($data);

                } while ($length != $red);
		return $buffer;
	} 
	
	public function recieve($socket) {
		//recieve header
		$header = "";		
		if ($header = socket_read($socket, SERVER_MSG_HEADER_SIZE)) {
			if (strlen($header) != SERVER_MSG_HEADER_SIZE) {
				return false; // Header corupt
			}
			
			//get items from header
			$header_parts = explode(chr(04), $header);
			$this->component = @$header_parts[0];
			$this->processType = @$header_parts[1];
			$this->name = @$header_parts[2];
			$text_data_size = @$header_parts[3];
			$bin_data_size = @$header_parts[4];
			$this->dataType = @$header_parts[5];

			$buffer = $this->readFromSocket($socket, $text_data_size);
			$bin_data = NULL;
			
			//recieve the Binary part of message, if some
			if ($bin_data_size != 0) {
				$bin_data = $this->readFromSocket($socket, $bin_data_size);
				$this->binaryData = $bin_data;
				$this->binaryDataSize = $bin_data_size;
			}
						
			$data_parts = explode(chr(06), $buffer);
			foreach ($data_parts as $data_part) {
				$data_part_parts = explode(chr(04), $data_part);
				$key = @$data_part_parts[0];
				$value = @$data_part_parts[1];
				$this->msgItems[$key] = $value;
			}
			
		} else {
			return false;
		}
		
		return true;	
		
	}
	
	public function send($socket) {
		
		//build message Header
		$data = "";
		$header = "";
		//add all data to send
		foreach($this->msgItems as $key => $value) {
			if ($data != "") {
				$data .= chr(06);
			}
			$data .= $key.chr(04).$value;
		}
		
		$header = $this->component;
		//header 128 byte
		$header .= chr(04);
		$header .= $this->processType;
		$header .= chr(04);
		$header .= $this->name;
		$header .= chr(04);
		$header .= strlen($data);
		$header .= chr(04);
		$header .= $this->binaryDataSize;
		$header .= chr(04);
		$header .= $this->dataType;  //data ist text/binary mode
		$header .= chr(04);
					
		if (strlen($header) > SERVER_MSG_HEADER_SIZE) {
			Log::e("Cant send Packet-Header, cause it is bigger than SERVER_MSG_HEADER_SIZE Byte");
			return false;
		}
		
		$header = str_pad($header, SERVER_MSG_HEADER_SIZE, chr(04));
		if (strlen($header) != SERVER_MSG_HEADER_SIZE) {
			Log::e("Cant send Packet-Header, cause it is != SERVER_MSG_HEADER_SIZE Byte");
			return false;
		}
		
		$written = socket_write($socket, $header.$data, strlen($header.$data));
		if ($written != strlen($header.$data)) {
			return false;
		}
		
		if ($this->binaryDataSize != 0) {
			$written = socket_write($socket, $this->binaryData, $this->binaryDataSize);
			if ($written != $this->binaryDataSize) {
				return false;
			}
		}
		
		return true;
	}
	

	
	
	
}
