//
//  ObserverClientCpp.cpp
//  k-observer-iphone
//
//  Created by vvv ооо on 06.09.12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

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

TObserverClient::TObserverClient()
    : MapType(0)
{
    
}

void TObserverClient::DestroyClientSocket()
{
    ClientSocket->CloseImmediate();
}


void TObserverClient::IoServiceRun()
{
    IoService.run();
    
    ReceiveCloseSignal();
    ReceiveCloseSignal.disconnect_all_slots();
    
}

void TObserverClient::CreateClientSocket(const char* address, const char* port)
{
    ClientSocket = boost::shared_ptr<TClientSocket>(new TClientSocket(IoService));
    
    ClientSocket->ReceiveMapSignal.connect(boost::bind(&TObserverClient::OnReceiveMapUpdate, this, _1));
    
    ClientSocket->ReceiveAlarmMapSignal.connect(boost::bind(&TObserverClient::OnReceiveAlarmMapUpdate, this, _1));
    
    ClientSocket->ReceiveMessageSignal.connect(boost::bind(&TObserverClient::OnReceiveMessage, this, _1, _2));
    
    ClientSocket->ReceiveAutorizationSentSignal.connect(boost::bind(&TObserverClient::OnAutorizationSend, this));
    
    ReceiveCloseSignal.connect(boost::bind(&TObserverClient::OnCloseSocket, this));
    
    ClientSocket->ReceiveForceCloseSignal.connect(boost::bind(&TObserverClient::OnReceiveQuit, this));
    
    ClientSocket->Open(std::string(address), std::string(port));
    
    IoServiceThread = boost::thread(boost::bind(&TObserverClient::IoServiceRun, this));
}



void TObserverClient::OnAutorizationSend()
{
    AppDelegateOnAutorizationSend();
}


void TObserverClient::UpdateUserInfo(const char* lastName,
                    const char* firstName,
                    const char* middleName,
                    const char* phoneNumber,
                    int uik,
                    int status)
{
    
    ClientSocket->UserInfo.LastName = std::string(lastName);
    ClientSocket->UserInfo.FirstName = std::string(firstName);
    ClientSocket->UserInfo.MiddleName = std::string(middleName);
    ClientSocket->UserInfo.PhoneNumber = std::string(phoneNumber);
    ClientSocket->UserInfo.Uik = uik;
    ClientSocket->UserInfo.Status = status;
    
    if (status == 1)
    {
        ClientSocket->UserInfo.MapState = 0;
    }
    
    ClientSocket->SendUserinfoUpdateThreaded();
    
}


void TObserverClient::RestartHeartbeatTimer()
{
    HeartbeatTimer = boost::shared_ptr<boost::asio::deadline_timer>(new boost::asio::deadline_timer(IoService, boost::posix_time::milliseconds(500)));
    
    HeartbeatTimer->async_wait(boost::bind(&TObserverClient::OnHeartbeat, this, boost::asio::placeholders::error));
}

void TObserverClient::RestartMapHeartbeatTimer()
{
    MapHeartbeatTimer = boost::shared_ptr<boost::asio::deadline_timer>(new boost::asio::deadline_timer(IoService, boost::posix_time::milliseconds(500)));
    
    MapHeartbeatTimer->async_wait(boost::bind(&TObserverClient::OnMapHeartbeat, this, boost::asio::placeholders::error));
}


void TObserverClient::OnHeartbeat(const boost::system::error_code& e)
{
    if (e)
    {
        return;
    }
    
    
    ClientSocket->SendHeartbeatThreaded();
    
    RestartHeartbeatTimer();
}

void TObserverClient::OnMapHeartbeat(const boost::system::error_code& e)
{
    if (e)
    {
        return;
    }
    
    if (MapType == 0)
    {
        ClientSocket->SendMapQueryThreaded();
    }
    else
    {
        ClientSocket->SendAlarmMapQueryThreaded();
    }
    
    RestartMapHeartbeatTimer();
}

void TObserverClient::OnReceiveMapUpdate(std::vector<TUserInfo> userInfoArr)
{
    
    UpdatingMapMutex.lock();
    
    UserInfoArr = userInfoArr;
    
    UpdatingMapMutex.unlock();
    
}


void TObserverClient::SwitchMapToAlarm()
{
    MapType = 1;
}

void TObserverClient::SwitchMapToCommon()
{
    MapType = 0;
}

bool TObserverClient::IsAlarmMap()
{
    return MapType == 1;
}

void TObserverClient::OnReceiveAlarmMapUpdate(std::vector<TUserInfo> userInfoArr)
{
    UpdatingMapMutex.lock();
    
    AlarmUserInfoArr = userInfoArr;
    
    UpdatingMapMutex.unlock();
}

void TObserverClient::OnReceiveMessage(TUserInfo userInfo, std::string message)
{
    
    AppDelegateAddNewMessage(userInfo, message);
    
}

void TObserverClient::SendMessage(const char* msg)
{
    std::string message(msg);
    
    ClientSocket->SendMessageThreaded(message);
}

void TObserverClient::OnCloseSocket()
{
    ClientSocket = boost::shared_ptr<TClientSocket>();
    
    IoService.reset();
    
    AppDelegateSendOnConnectionClosed();
    
}

void TObserverClient::OnReceiveQuit()
{
    AppDelegateSendOnReceiveQuit();
    
}