// Copyright 1994 by Jon Dart
// epdstat.cpp : implementation file
//

#include "stdafx.h"
#include "epdstat.h"
#include "epdrec.h"
#include "chessio.h"
#include "globals.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// EpdStatusDialog dialog

static char tempfile[MAX_PATH];

EpdStatusDialog::EpdStatusDialog(CWnd* pParent, 
                                 CString &filename,
                                 ifstream &strm,
                                 Board &board,
                                 BOOL annotate)
        : CDialog(EpdStatusDialog::IDD, pParent),ifs(strm),
          current_board(board), parent((CArasanView*)pParent),
          do_annotation(annotate)
{
        //{{AFX_DATA_INIT(EpdStatusDialog)
        m_EpdID = "";
        m_EpdRecord = "1";
        //}}AFX_DATA_INIT
        // get just the name portion of the filename:
        char *p = filename.GetBuffer(filename.GetLength());
        char *q = p + filename.GetLength();
        while (q != p && *q != '\\' && *q != ':') --q;
        
        // show the user what file we're reading:
        AfxFormatString1(m_EpdFile,IDS_EPD_FILE,q == p ? p : q+1);
        filename.ReleaseBuffer();
        pathName = filename;
        running = cancelled = FALSE;
}

BOOL EpdStatusDialog::OnInitDialog()
{
    BOOL result = CDialog::OnInitDialog();
    
    return result;
}


void EpdStatusDialog::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(EpdStatusDialog)
        DDX_Text(pDX, ID_EPD_FILE, m_EpdFile);
        DDX_Text(pDX, ID_EPD_ID, m_EpdID);
        DDX_Text(pDX, ID_EPD_RECORD, m_EpdRecord);
        //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(EpdStatusDialog, CDialog)
        //{{AFX_MSG_MAP(EpdStatusDialog)
        ON_WM_SHOWWINDOW()
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// EpdStatusDialog message handlers

void EpdStatusDialog::OnCancel()
{
        // TODO: Add extra cleanup here
    if (running)
    {
        parent->terminate_search();
        cancelled = TRUE;
    }
    else    
        CDialog::OnCancel();
}

BOOL EpdStatusDialog::OnCommand(WPARAM wParam, LPARAM lParam)
{
    // for some reason, the Cancel command doesn't get dispatched..
    // route it to the handler ourselves.
    if (wParam == IDCANCEL)
    {
        OnCancel();
        return TRUE;
    }
    else if (wParam != ID_EXECUTE_EPD)
        return FALSE; // not processed
    EPD_Record *rec;
    DWORD count = 0;

#ifdef _WIN32
    char path[MAX_PATH]; 
    GetTempPath(MAX_PATH,path);
    GetTempFileName(path,"Arasan", 0, tempfile);
#else
    GetTempFileName(GetTempDrive('A'),"Arasan", 0, tempfile);
#endif

    ofstream outfile;
    if (do_annotation)
    {
        outfile.open(tempfile,ios::out | ios::trunc); 
    }
    running = TRUE;
    while (!cancelled && (rec = ChessIO::read_epd_record(ifs,current_board)) != NULL)
    {
       if (rec->has_error())
       {
           if (MessageBox(rec->get_error(),"Error",MB_OKCANCEL) == IDCANCEL)
               cancelled = TRUE;
           delete rec;
           continue;
       }
       
       theView->draw_board();    
       theView->show_side(); 
       
       // Yield so UI isn't "dead" (e.g. repaints can occur)
       MSG msg;
       while (::PeekMessage(&msg,NULL,0,0,PM_REMOVE))
       {
             ::TranslateMessage(&msg);
             ::DispatchMessage(&msg);
       }
       
       count++;
       if (rec->has_val("id"))
       { 
          CString idstr;
          rec->get_val("id",idstr);
          /**
          theLog->write("===  EPD record: ");
          theLog->write((LPCSTR)idstr);
          theLog->write(" read.");
          theLog->write_eol();
          ***/
          m_EpdID = idstr;
       }
       char countstr[10];
       wsprintf(countstr,"%ld",count);
       m_EpdRecord = countstr;
       UpdateData(FALSE);
       game_moves->clear();
       parent->computer_plays(current_board.Side());
       if (do_annotation)
       {
          ChessIO::annotate_epd_record(rec,current_board,outfile);
       }
       else
       {
          ChessIO::execute_epd_record(rec,current_board);
       }
       delete rec;
    }
    current_board.Reset();
    running = FALSE;
    if (do_annotation)
    {
       outfile.close();
       ifs.close();
       if (!cancelled)
       {
           // copy temporary file onto input file, replacing it
           CFile newfile(pathName,CFile::modeWrite);
           CFile readfile(tempfile,CFile::modeRead);
           const BUFSIZE = 4096;
           char *buf = new char[BUFSIZE];
           UINT nRead;
           while (nRead = readfile.Read(buf,BUFSIZE))
           {
               newfile.Write(buf,nRead);
           }
           delete [] buf;
       }
       // remove temporary file
       CFile::Remove(tempfile);
    }
    PostMessage(WM_COMMAND, IDCANCEL,0L);       

    return TRUE;
}

void EpdStatusDialog::OnShowWindow(BOOL bShow, UINT nStatus) 
{
    CDialog::OnShowWindow(bShow, nStatus);

    PostMessage(WM_COMMAND,ID_EXECUTE_EPD);
}
