#include "wsTimerThread.h"
#include <iostream>

#include "wsClientMgr.h"
#include "constdef.h"

namespace YA
{
	wsTimerThread::wsTimerThread()
	{
		__Reset();

		__LastSendTime = { 0 };
		__LastSendTime.tm_year = 1970 - 1900;
		__LastSendTime.tm_mon  = 1;
		__LastSendTime.tm_mday = 1;
	}

	wsTimerThread::~wsTimerThread()
	{
		Stop();
	}

	void wsTimerThread::Start()
	{
		__Running = true;
		__Thread.reset( new boost::thread( boost::bind( &wsTimerThread::_ThreadFunc, this, this ) ) );
		__Thread->detach();
	}

	void wsTimerThread::Stop()
	{
		std::cout << "::Stop() begin" << std::endl;

		__Enable = false;

		if ( __Running )
		{
			boost::unique_lock<boost::mutex> lock( __ExitMutex );
			__ExitCond.wait( lock );
		}

		__Reset();

		std::cout << "::Stop() end" << std::endl;
	}

	void wsTimerThread::__Reset()
	{
		__Enable  = true;
		__Running = false;
	}

	void wsTimerThread::__ChkConfig()
	{
		if ( __Config.SendInterval < MIN_SEND_INTERVAL )
		{
			__Config.SendInterval = MIN_SEND_INTERVAL;
		}
	}

	void wsTimerThread::__SendCardPos()
	{
		std::map<int, _CARD_POS_> CardPosList;
		__CardPosList.copy( CardPosList );
		std::string jsCardPos = __jsBuilder.BuildCardPos( CardPosList );
		swsClientMgr.send( JSON_CMD_VALUE_PUSH, jsCardPos );
	}

	void wsTimerThread::_ThreadFunc( wsTimerThread * pOwner )
	{
		while ( pOwner->__Enable )
		{
			std::tm *Now;
			std::time_t t;
			t = time( 0 );
			Now = localtime( &t );
			int seconds = (int)std::difftime( mktime( Now ), mktime( &__LastSendTime ) );

			if ( seconds >= pOwner->__Config.SendInterval )
			{
				pOwner->__SendCardPos();
				__LastSendTime = *Now;
			}

			boost::this_thread::sleep( boost::posix_time::millisec( 1 ) );
		}

		pOwner->__ExitCond.notify_one();
	}

	void wsTimerThread::Init( const _THREAD_CONFIG_ & Config )
	{
		__Config = Config;
		__ChkConfig();
	}

	void wsTimerThread::upt_card_pos( const _CARD_POS_ & pos )
	{
		//如果已存在就更新,否则插入
		if ( __CardPosList.seek( pos.ID ) )
		{
			__CardPosList.update( pos.ID, pos );
		}
		else
		{
			__CardPosList.insert( pos.ID, pos );
		}
	}

	void wsTimerThread::del_card_pos( const _CARD_POS_ & pos )
	{
		__CardPosList.erase( pos.ID );
	}
}