/* -*-mode: C; fill-column: 77; c-basic-offset: 4; -*- */
/* 
 * Copyright 2002 by Eric House (fixin@peak.org).  All rights reserved.
 *
 * 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include "ceginfo.h"
#include "cemain.h"
#include "ceutil.h"
#include "cedict.h"
#include "strutils.h"

#define NUM_COLS 3

/* forward decls */
static XP_UCHAR* bname( XP_UCHAR* in );

static void
loadFromGameInfo( HWND hDlg, CEAppGlobals* globals, GameInfoState* giState )
{
    XP_U16 i;
    CurGameInfo* gi = &globals->gameInfo;
    wchar_t widebuf[32];
    XP_UCHAR* str;

    for ( i = 0; i < MAX_NUM_PLAYERS; ++i ) {
        LocalPlayer* lp = &gi->players[i];
        XP_U16 resID;
        XP_U16 idToCheck;

        /* set the robot checkbox */
        resID = ROBOT_CHECK1 + (NUM_COLS*i);
        idToCheck = lp->isRobot? resID : 0;
        CheckRadioButton( hDlg, resID, resID, idToCheck );

        /* set the player name */
        resID = NAME_EDIT1 + (NUM_COLS*i);
        ceSetDlgItemText( hDlg, resID, lp->name );

        /* set the password, if any */

        /* put a string in the moronic combobox */
        swprintf( widebuf, L"%d", i + 1 );

        SendDlgItemMessage( hDlg, IDC_NPLAYERSCOMBO, CB_ADDSTRING, 0, 
                            (long)widebuf );
    }

    /* set the player num box */
    SendDlgItemMessage( hDlg, IDC_NPLAYERSCOMBO, CB_SETCURSEL, 
                        gi->nPlayers-1, 0L );

    /* set the dictionary name */
    if ( !!gi->dictName ) { 
        str = bname( gi->dictName );
        XP_MEMCPY( giState->newDictName, gi->dictName, 
                   (XP_U16)XP_STRLEN(gi->dictName) );
    } else {
        str = "--pick--";
    }
    XP_MEMSET( widebuf, 0, sizeof(widebuf) );
    MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, strlen(str),
                         widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
    SendDlgItemMessage( hDlg, IDC_DICTBUTTON, WM_SETTEXT, 0, (long)widebuf );

    if ( !giState->isNewGame ) {
        XP_U16 disableIDs[] = { IDC_NPLAYERSCOMBO, 
                                IDC_DICTBUTTON};
        XP_U16 i;
        for( i = 0; i < sizeof(disableIDs)/sizeof(disableIDs[0]); ++i ) {
            ceEnOrDisable( hDlg, disableIDs[i], XP_FALSE );
        }
    }

} /* loadFromGameInfo */

static void
ceAdjustVisibility( HWND hDlg, XP_U16 nPlayers )
{
    XP_U16 i, j;

    for ( i = 0; i < MAX_NUM_PLAYERS; ++i ) {
        XP_Bool visible = i < nPlayers;
        XP_U16 resBase = NAME_EDIT1 + (NUM_COLS*i);

        for ( j = 0; j < NUM_COLS; ++j ) {
            ceShowOrHide( hDlg, (XP_U16)(resBase+j), visible );
        }
    }
} /* ceAdjustVisibility */

static void
getStringAndReplace( CEAppGlobals* globals, HWND hDlg, XP_U16 id, 
                     XP_UCHAR** sloc ) 
{
    XP_UCHAR cbuf[33];
    XP_U16 len;

    len = sizeof(cbuf);
    ceGetDlgItemText( hDlg, id, cbuf, &len );

    replaceStringIfDifferent( MPPARM(globals->mpool) sloc, cbuf );
} /* getStringAndReplace */

static void
stateToGameInfo( HWND hDlg, CEAppGlobals* globals, GameInfoState* giState )
{
    XP_U16 i;
    CurGameInfo* gi = &globals->gameInfo;
    XP_U16 nPlayers;
    XP_Bool timerOn;

    nPlayers = 1 + (XP_U16)SendDlgItemMessage( hDlg, IDC_NPLAYERSCOMBO, 
                                               CB_GETCURSEL, 0, 0 );
    gi->nPlayers = (XP_U8)nPlayers;
    XP_DEBUGF( "Set nPlayers to %d", nPlayers );

    for ( i = 0; i < nPlayers; ++i ) {
        XP_U16 id;
        XP_Bool checked;
        LocalPlayer* lp = &gi->players[i];

        /* robot */
        id = ROBOT_CHECK1 + (NUM_COLS * i);
        checked = (XP_Bool)SendDlgItemMessage( 
                                              hDlg, id, BM_GETCHECK, 0, 0 );
        lp->isRobot = checked;

        /* password */
        id = PASS_EDIT1 + (NUM_COLS * i);
        getStringAndReplace( globals, hDlg, id, &lp->password );

        /* name */
        id = NAME_EDIT1 + (NUM_COLS * i);
        getStringAndReplace( globals, hDlg, id, &lp->name );
    }

    /* dictionary */
    replaceStringIfDifferent( MPPARM(globals->mpool) &gi->dictName,
                              giState->newDictName );

    /* timer */
    timerOn = SendDlgItemMessage( hDlg, TIMER_CHECK, BM_GETCHECK, 0, 0 );
    gi->timerEnabled = timerOn;
    if ( timerOn ) {
        XP_UCHAR numBuf[10];
        XP_U16 len = sizeof(numBuf);
        ceGetDlgItemText( hDlg, TIMER_EDIT, numBuf, &len );
        if ( len > 0 ) {
            XP_U16 num = atoi( numBuf );
            gi->gameSeconds = num * 60;
        }
    }
    
    /* preferences */
    if ( giState->prefsChanged ) {
        loadCurPrefsFromState( &globals->appPrefs, gi, &giState->prefsPrefs );
    }

} /* stateToGameInfo */

static void
handleOptionsButton( HWND hDlg, CEAppGlobals* globals, GameInfoState* giState )
{
    PrefsDlgState state;

    /* need to keep my stuff in a temporary place and to read back out of it
       if launched a second time before the user's cancelled or not out of
       the calling dlg.*/

    if ( WrapPrefsDialog( hDlg, globals, &state, &giState->prefsPrefs,
                          giState->isNewGame ) ) {
        giState->prefsChanged = XP_TRUE;
        /* nothing to do until user finally does confirm the parent dialog */
    }
} /* handleOptionsButton */

LRESULT CALLBACK
GameInfo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    CEAppGlobals* globals;
    XP_U16 id;
    GameInfoState* giState;

    if ( message == WM_INITDIALOG ) {

        SetWindowLong( hDlg, GWL_USERDATA, lParam );
        giState = (GameInfoState*)lParam;
        globals = giState->globals;

        positionDlg( hDlg );

        loadFromGameInfo( hDlg, globals, giState );
        loadStateFromCurPrefs( &globals->appPrefs, &globals->gameInfo, 
                               &giState->prefsPrefs );

        ceAdjustVisibility( hDlg, globals->gameInfo.nPlayers );

        return TRUE;

    } else {
        giState = (GameInfoState*)GetWindowLong( hDlg, GWL_USERDATA );
        globals = giState->globals;

        switch (message) {
        case WM_COMMAND:
            id = LOWORD(wParam);
            switch( id ) {

            case ROBOT_CHECK1:
            case ROBOT_CHECK2:
            case ROBOT_CHECK3:
            case ROBOT_CHECK4:
                break;

            case IDC_NPLAYERSCOMBO:
                if ( HIWORD(wParam) == CBN_SELCHANGE ) {
                    if ( giState->isNewGame ) {    /* ignore if in info mode */
                        XP_U16 sel;
                        sel = (XP_U16)SendDlgItemMessage( hDlg, IDC_NPLAYERSCOMBO,
                                                          CB_GETCURSEL, 0, 0L );
                        ceAdjustVisibility( hDlg, (XP_U16)(sel+1) );
                    }
                }
                break;

            case IDC_DICTBUTTON:
                if ( giState->isNewGame ) { /* ignore if in info mode */
                    giState->newDictName[0] = 0;
                    if ( ce_pickDictFile( globals, giState->newDictName,
                                          sizeof(giState->newDictName) ) ) {
                        XP_UCHAR* basename = bname(giState->newDictName);
                        ceSetDlgItemText( hDlg, id, basename );
                    }
                }
                break;

            case OPTIONS_BUTTON:
                handleOptionsButton( hDlg, globals, giState );
                break;

            case IDOK:
                stateToGameInfo( hDlg, globals, giState );
            case IDCANCEL:
                EndDialog(hDlg, id);
                giState->userCancelled = id == IDCANCEL;
                return TRUE;
            }
            break;
            /*     case WM_CLOSE: */
            /* 	EndDialog(hDlg, id); */
            /* 	return TRUE; */
            /*     default: */
            /* 	return DefWindowProc(hDlg, message, wParam, lParam); */
        }
    }
    return FALSE;
} /* GameInfo */

static XP_UCHAR*
bname( XP_UCHAR* in )
{
    XP_U16 len = (XP_U16)XP_STRLEN(in);
    XP_UCHAR* out = in + len - 1;

    while ( *out != '\\' && out >= in ) {
        --out;
    }
    return out + 1;
} /* bname */
