/*==LICENSE==*

CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011  Cyan Worlds, Inc.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

You can contact Cyan Worlds, Inc. by email legal@cyan.com
 or by snail mail at:
      Cyan Worlds, Inc.
      14617 N Newport Hwy
      Mead, WA   99021

*==LICENSE==*/
/*****************************************************************************
*
*   $/Plasma20/Sources/Plasma/FeatureLib/pfGameMgr/TicTacToe/pfGmTicTacToe.cpp
*   
***/

#define USES_GAME_HEEK
#include "../Pch.h"
#pragma hdrstop


/*****************************************************************************
*
*   Local types
*
***/

struct IHeek {
    pfGmHeek *      gameCli;

    IHeek (pfGmHeek * gameCli);

    // pfGameCli event notification handlers
    void Recv           (GameMsgHeader * msg, void * param);
    void OnPlayerJoined (const Srv2Cli_Game_PlayerJoined & msg);
    void OnPlayerLeft   (const Srv2Cli_Game_PlayerLeft & msg);
    void OnInviteFailed (const Srv2Cli_Game_InviteFailed & msg);
    void OnOwnerChange  (const Srv2Cli_Game_OwnerChange & msg);

    // Heek network message handlers    
    void RecvPlayGame       (const Srv2Cli_Heek_PlayGame & msg, void * param);
    void RecvGoodbye        (const Srv2Cli_Heek_Goodbye & msg, void * param);
    void RecvWelcome        (const Srv2Cli_Heek_Welcome & msg, void * param);
    void RecvDrop           (const Srv2Cli_Heek_Drop & msg, void * param);
    void RecvSetup          (const Srv2Cli_Heek_Setup & msg, void * param);
    void RecvLightState     (const Srv2Cli_Heek_LightState & msg, void * param);
    void RecvInterfaceState (const Srv2Cli_Heek_InterfaceState & msg, void * param);
    void RecvCountdownState (const Srv2Cli_Heek_CountdownState & msg, void * param);
    void RecvWinLose        (const Srv2Cli_Heek_WinLose & msg, void * param);
    void RecvGameWin        (const Srv2Cli_Heek_GameWin & msg, void * param);
    void RecvPointUpdate    (const Srv2Cli_Heek_PointUpdate & msg, void * param);
};


/*****************************************************************************
*
*   Factory functions
*
***/

//============================================================================
static pfGameCli * HeekFactory (
unsigned    gameId,
plKey       receiver
) {
    return NEWZERO(pfGmHeek)(gameId, receiver);
}

//============================================================================
AUTO_INIT_FUNC(RegisterHeek) {
    static GameTypeReg reg = {
        HeekFactory,
        kGameTypeId_Heek,
        L"Heek"
    };

    GameMgrRegisterGameType(reg);
}


/*****************************************************************************
*
*   IHeek
*
***/

//============================================================================
IHeek::IHeek (pfGmHeek * gameCli)
:   gameCli(gameCli)
{
}

//============================================================================
void IHeek::OnPlayerJoined (const Srv2Cli_Game_PlayerJoined & msg) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::OnPlayerLeft (const Srv2Cli_Game_PlayerLeft & msg) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::OnInviteFailed (const Srv2Cli_Game_InviteFailed & msg) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::OnOwnerChange (const Srv2Cli_Game_OwnerChange & msg) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvPlayGame (const Srv2Cli_Heek_PlayGame & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvGoodbye (const Srv2Cli_Heek_Goodbye & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvWelcome (const Srv2Cli_Heek_Welcome & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvDrop (const Srv2Cli_Heek_Drop & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvSetup (const Srv2Cli_Heek_Setup & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvLightState (const Srv2Cli_Heek_LightState & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvInterfaceState (const Srv2Cli_Heek_InterfaceState & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvCountdownState (const Srv2Cli_Heek_CountdownState & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvWinLose (const Srv2Cli_Heek_WinLose & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvGameWin (const Srv2Cli_Heek_GameWin & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}

//============================================================================
void IHeek::RecvPointUpdate (const Srv2Cli_Heek_PointUpdate & msg, void * param) {
    pfGameCliMsg * gameCliMsg = NEWZERO(pfGameCliMsg);
    gameCliMsg->Set(gameCli, msg);
    gameCliMsg->Send(gameCli->GetReceiver());
}


/*****************************************************************************
*
*   pfGmHeek
*
***/

//============================================================================
pfGmHeek::pfGmHeek (
    unsigned    gameId,
    plKey       receiver
)
:   pfGameCli(gameId, receiver)
{
    internal = NEWZERO(IHeek)(this);
}

//============================================================================
pfGmHeek::~pfGmHeek () {
    DEL(internal);
}

//============================================================================
void pfGmHeek::Recv (GameMsgHeader * msg, void * param) {
#define DISPATCH(a) case kSrv2Cli_Heek_##a: {                                       \
                        const Srv2Cli_Heek_##a & m = *(const Srv2Cli_Heek_##a *)msg;    \
                        internal->Recv##a(m, param);                                \
                    }                                                               \
                    break;

    switch (msg->messageId) {
        DISPATCH(PlayGame);
        DISPATCH(Goodbye);
        DISPATCH(Welcome);
        DISPATCH(Drop);
        DISPATCH(Setup);
        DISPATCH(LightState);
        DISPATCH(InterfaceState);
        DISPATCH(CountdownState);
        DISPATCH(WinLose);
        DISPATCH(GameWin);
        DISPATCH(PointUpdate);
        DEFAULT_FATAL(msg->messageId);
    }
#undef DISPATCH
}

//============================================================================
void pfGmHeek::OnPlayerJoined (const Srv2Cli_Game_PlayerJoined & msg) {
    internal->OnPlayerJoined(msg);
}

//============================================================================
void pfGmHeek::OnPlayerLeft (const Srv2Cli_Game_PlayerLeft & msg) {
    internal->OnPlayerLeft(msg);
}

//============================================================================
void pfGmHeek::OnInviteFailed (const Srv2Cli_Game_InviteFailed & msg) {
    internal->OnInviteFailed(msg);
}

//============================================================================
void pfGmHeek::OnOwnerChange (const Srv2Cli_Game_OwnerChange & msg) {
    internal->OnOwnerChange(msg);
}

//============================================================================
void pfGmHeek::PlayGame (unsigned position, dword points, const wchar name[]) {
    Cli2Srv_Heek_PlayGame msg;
    msg.messageId       = kCli2Srv_Heek_PlayGame;
    msg.messageBytes    = sizeof(msg);
    msg.recvGameId      = GetGameId();  // send to GameSrv on server
    msg.transId         = 0;

    msg.position        = (byte)position;
    msg.points          = points;
    StrCopy(msg.name, name, arrsize(msg.name));

    GameMgrSend(&msg);
}

//============================================================================
void pfGmHeek::LeaveGame () {
    Cli2Srv_Heek_LeaveGame msg;
    msg.messageId       = kCli2Srv_Heek_LeaveGame;
    msg.messageBytes    = sizeof(msg);
    msg.recvGameId      = GetGameId();  // send to GameSrv on server
    msg.transId         = 0;

    GameMgrSend(&msg);
}

//============================================================================
void pfGmHeek::Choose (EHeekChoice choice) {
    Cli2Srv_Heek_Choose msg;
    msg.messageId       = kCli2Srv_Heek_Choose;
    msg.messageBytes    = sizeof(msg);
    msg.recvGameId      = GetGameId();  // send to GameSrv on server
    msg.transId         = 0;

    msg.choice = (byte)choice;

    GameMgrSend(&msg);
}

//============================================================================
void pfGmHeek::SequenceFinished (EHeekSeqFinished seq) {
    Cli2Srv_Heek_SeqFinished msg;
    msg.messageId       = kCli2Srv_Heek_SeqFinished;
    msg.messageBytes    = sizeof(msg);
    msg.recvGameId      = GetGameId();  // send to GameSrv on server
    msg.transId         = 0;

    msg.seqFinished = (byte)seq;

    GameMgrSend(&msg);
}