/*
	ZNetClient.hpp
	Author: Patrick Baggett	<ptbaggett@762studios.com>
	Created: 7/11/2013

	Purpose:

	ZNetClient -- extends ZNetHost to provide a client

	License:
	
	Copyright 2013, 762 Studios
*/

#pragma once

#ifndef _ZNETCLIENT_HPP
#define _ZNETCLIENT_HPP

#include <ZNet/ZNetHost.hpp>
#include <ZNet/ZNetPeer.hpp>

class ZNetClient : public ZNetHost
{
	public:
		ZNetClient();
		~ZNetClient();

		/*
			ZNetClient::Update()
			
			Implements ZNetHost::Update().
			
			This should be called to read incoming network data and send outgoing traffic. Events
			are only generated by calling Update().

			@return (int) - Less than 0: error. 0: OK
		*/
		int Update();
		
		/*
			ZNetClient::Connect()
			
			Initiates a connection to the given host. This method is asynchronous, so an event is
			generated. However, if this returns false, then no events will be generated because
			an error has occurred locally.
		*/
		bool Connect(SST_Socket socket, SST_NetAddress* addr, uint32_t nrChannels, uint32_t userData);
	
		/*
			ZNetClient::SendPacket()
			
			Sends a packet to the server via a certain channel. Use ZNetPacket::Release()
			when the packet is no longer needed.
			
			@param packet - The packet to broadcast
			@param channelId - The channel ID
		*/
		void SendPacket(ZNetPacket* packet, uint32_t channelId);
		

		/*
			ZNetClient::Disconnect()
			
			Begins a graceful disconnect. Update() should be called until an event of type DISCONNECT occurs,
			or a timeout happens. If a timeout is reached, Reset() should be used.
			
		*/
		void Disconnect();

		/*
			ZNetClient::Reset()
			
			Disconnects from the server, but does not inform him/her that the disconnect has occurred.
			This should only be used when a graceful disconnect does not work or when aborting
			the client. No local event is generated, so any cleanup must be done immediately.
		*/
		void Reset();

		/*
			ZNetClient::GetServer()
			
			Gets the ZNetPeer object that represents the server. If the client is 
			not connected, then this returns NULL.
		*/
		ZNetPeer* GetServer() const;
		
		bool IsConnected() const { return connectedFlag; }

	private:
		ZNetPeer server;
		bool connectedFlag;

		/* Handle a raw packet sent by the server */
		void HandlePacket(const uint8_t* data, uint32_t dataSize);
};

#endif