
/*********************************************************************
*   < _SPEED.H >
**********************************************************************
*   SPEEDの設計
**********************************************************************
*                                                   Copyright (C) 2005
*   Programed by Ochi
*********************************************************************/

#ifndef HEADER_SPEED
#define HEADER_SPEED

#include "developer.h"

#define EDIT_DEBUG 1000             // デバッグ画面のID
#define TIMER_ELAPSE 1001           // タイマーのID
#define STATIC_TIMER 1002           // タイマーのウィンドウのID
#define INI_SETUP "./setup.ini"     // 設定ファイルの場所

enum GameInfo_Message
{
    ////////////////////////////////////////
    // ゲームの状態
    NOTHING=1,  // 開始されていない
    CON_WAIT,   // 接続待ち
    CONNECT,    // 接続され、待機中
    MEASURE,    // 速度計測中
    PLAY,       // プレイ中
    PAUSE_0,    // ゲーム一時停止 どちらも開始しようとしていない状態
    PAUSE_1,    // ゲーム一時停止 どちらかがゲームを開始しようとしている状態
    WIN,        // 勝ち
    DRAW,       // 引き分け
    DEFEAT,     // 負け
    NEXTGAME,   // プレイが終了し、開始待ち
    ////////////////////////////////////////
    // 命令郡
    FIRST,
    UPDATE,
    PAUSE,
    RESTART,
    INVISIBLE,
    OK,
    NG,
    BUF,
};

/*********************************************************************
* プロトタイプ宣言
*********************************************************************/
DWORD WINAPI Thread_Connect ( LPVOID lpParam );     // 接続スレッド関数
DWORD WINAPI Thread_RecvMessage ( LPVOID lpParam ); // 本当はCNetWorkに組み込みたい
DWORD WINAPI Thread_Restart ( LPVOID lpParam );     // Recvの処理中にさらにRecvしたい時に使う…

/*********************************************************************
* カードクラス
*********************************************************************/
class CCards
{
private:
    // カードの状態
    int nBa[2];             // 場のカード（最大2枚）
    int nTefuda[2][8];      // 手札のカード（最大4枚）
    int nYama[2][32];       // 山のカード（最大27枚）
    int nBaBuf[2];          // 場のカードのバッファ
    int nTefudaBuf[2][8];   // 手札のカードのバッファ
    int nYamaBuf[2][32];    // 山のカードのバッファ

public:
    CCards();
    // カードのデータを外部で読み取るための関数
    bool    SetBa( int* );
    bool    SetTefuda( int* );
    bool    SetYama( int* );
    bool    SetBaBuf( int* );
    bool    SetTefudaBuf( int* );
    bool    SetYamaBuf( int* );
    bool    ExtraSet( void );
    bool    ExtraSetToBuf( int*, int*, int* );

    char*   Decode ( int );         // カードを数値から記号に戻す
    int     Encode ( char* );       // カードを記号から数値に変換
    bool    Judgment ( int, int );  // カードが置けるかの判断
    bool    JudgmentStop( void );   // ゲームがストップしたかの判断
    void    SetupDemo ( void );     // カードを起動時の状態にする
    void    SetupCards ( void );    // カードを混ぜて配布する
    bool    SetRestart ( void );    // ゲームが再開されたときの動作
    int     Update ( char*, int );  // カードを更新する
};

/*********************************************************************
* 描画クラス
*********************************************************************/
class CDraw
{
private:
    HWND    hWnd;       // ハンドルウィンドウ
    HDC     hMemoryDC;  // メモリデバイスコンテキスト
    HDC     hSaveDC;    // カードを移動する時に、そのカード以外の状態をセーブするHDC

public:
    void    FormatDC ( HWND );          // DCを初期化する
    bool    DrawCards ( CCards, bool, int );    // カードを描画する
    void    LoadAllImage ( void );      // 全画像をロードする
    HWND    ReturnHWND ( void );        // hWndを渡す
    HDC     ReturnMemoryDC ( void );    // hMemoryDCを渡す
    HDC*    ReturnSaveDC ( void );      // hSaveDCを渡す
};

/*********************************************************************
* タイマークラス
*********************************************************************/
class CTimer
{
private:
    LARGE_INTEGER tsc;
    unsigned long KeepTime;         // タイマーが開始された時刻
    unsigned long RealTime;         // 経過時間

public:
    void Start ( void );            // タイマースタート
    unsigned long Time ( void );    // 時刻を取得

};

/*********************************************************************
* ゲームクラス
*********************************************************************/
class CGame
{
private:
    CCards      cCards;                 // カードを操作するクラス
    CDraw       cDraw;                  // 描画関係のクラス
    CSocket     cSocket;                // ソケットクラス
    bool        fLButton;               // 左ボタンのフラグ　押されている:true
    bool        fWaitAdmission;         // 許可街のメッセージがあるか
    int         GameInfo;               // ゲームの進行状況
    long        lPacketCycle;           // パケット往復にかかる時間
    long        lMyTime;                // メッセージを送信した時間
    HANDLE      hConnect;               // 接続スレッドのハンドル
    HANDLE      hReceive;               // スレッドのハンドル
    int         nCardNo;                // クリックされたカードの番号
    int         nMessageNo;             // メッセージの番号
    POINT       ptCard;                 // カード移動時にカードが摘まれた位置
    POINT       ptMouse;                // カード移動時のマウスポインタの位置
    char        szStackMsg[RECV_UDP];   // 許可待ちのメッセージ
    DWORD       thConnect;              // 接続スレッド
    DWORD       thReceive;              // メッセージ受信スレッド

    bool    StartClient ( void );       // クライアントとしてゲームが開始された
    bool    StartServer ( void );       // サーバとしてゲームが開始された

public:
    CTimer      cTimer;                 // タイマークラス
    CTimer      cCycleTimer;            // パケットの往復時間を監視
    CGame() { GameInfo=NOTHING; fLButton=false; fWaitAdmission=false; }
    ~CGame();
    // ゲーム進行に関わる
    bool    Connect ( void );           // 相手と接続する
    bool    ConnectByThread ( void );   // マルチスレッドで接続を行う場所
    bool    FormatStartUp ( HWND );     // カードと画面を起動時の状態にセット
    bool    MeasureSpeed( int, int, int );  // 通信速度を計測する
    bool    NextGame ( int, bool );     // 現在のゲームを破棄し、次のゲームを開始する
    bool    RecvMessage ( void );       // メッセージを受信・解読し、実行する
    bool    Restart ( int );            // ゲームの一時中断を抜ける
    bool    SendCards ( int );          // 現在のカード状態を送信する
    bool    SNTPAdjustTime( char* );    // SNTPで時間を合わせる
    // インターフェース
    bool    LButtonDown ( POINT );      // 左クリック時の処理
    bool    LButtonUp ( POINT );        // マウスが放されたときの処理
    bool    MouseMove ( POINT );        // マウスが動いた時の処理
    bool    RButtonDown ( POINT );      // 右クリック時の処理
    // その他の関数
    void    Debug_Send ( const char* ); // Degug用
    void    DrawTimer ( void );         // タイマーを描画する
    bool    ReturnLButton ( void );     // fLButtonを返す
    int     ReturnGameInfo ( void );    // ゲームの状態を返す
    CCards* ReturnCCardsPtr ( void );   // &CCardsを返す　外部からカード情報を読み取りたい場合に使う
    HDC     ReturnHDC ( void );         // メモリDCを返す

    // 本当はThread_RecvMessageを中に入れたい
    void    StartConnectThread()
    {
        hConnect = CreateThread( NULL, 0, Thread_Connect, NULL, 0, &thConnect );
    }
    void    StartRecvThread()
    {
        hReceive = CreateThread( NULL, 0, Thread_RecvMessage, NULL, 0, &thReceive );
    }
};

// 実際のものはWM_CREATE.cppで宣言されている
extern  CGame       cGame;

#endif
