// ---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "UCppModelFrame.h"
#include <System.StrUtils.hpp>
#include <System.IOUtils.hpp>
// #include <synchapi.h>

// ---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TCppModelFrame *CppModelFrame;

// ---------------------------------------------------------------------------
void ProgressChanged(void * hnd, float progress )
  {
  TCppModelFrame * F=(TCppModelFrame* )hnd;
  F->ProgressBar1->Position = static_cast<int>(progress * 100);
  }

// ---------------------------------------------------------------------------
void Finished(void * hnd)
  {
     TCppModelFrame * F=(TCppModelFrame* )hnd;
  if (F->CancelPending)
    {
    F->MemoMsg->Lines->Add("cancelled");
    }
  else
    {
    F->MemoMsg->Lines->Add("finished");
	}
  F->EnableButtons();
  F->CancelPending = false;
  F->btCancel->Enabled = false;
  F->ProgressBar1->Position = 0;
  F->IsWorking = false;
  }

// ---------------------------------------------------------------------------
void PrintMessageMultiLine(void * hnd,const char* msg)
  {
   TCppModelFrame * F=(TCppModelFrame* )hnd;

   TStringDynArray tmp = SplitString(msg, "\n");
  for (int i = 0; i < tmp.Length; i++)
    {
    F->MemoMsg->Lines->Add(tmp[i]);
    }
  }

// ---------------------------------------------------------------------------
void TCppModelFrame::DisableButtons()
  {
  btSave->Enabled = false;
  btReload->Enabled = false;
  btOptimizeParams->Enabled = false;
  btOptimizeWeights->Enabled = false;
  btCrossVal->Enabled = false;
  btPrintClfINfo->Enabled = false;
  }

// ---------------------------------------------------------------------------
void TCppModelFrame::EnableButtons()
  {
  btSave->Enabled = true;
  btReload->Enabled = true;
  btOptimizeParams->Enabled = true;
  btOptimizeWeights->Enabled = true;
  btCrossVal->Enabled = true;
  btPrintClfINfo->Enabled = true;
  }

// ---------------------------------------------------------------------------
char* TCppModelFrame::_getFullFileName(const char* clfFileName)
  {
  return AnsiString(TPath::Combine(ExtractFileDir(Application->ExeName), clfFileName)).c_str();
  }

// ---------------------------------------------------------------------------
int TCppModelFrame::Predict(const double *data, unsigned n_samples, int* y_pred)
{
	if(!IsWorking)
	{
		return CppModel->Predict(data, n_samples, y_pred);
	}
	else
	{
        return -1;
    }
}
// ---------------------------------------------------------------------------
__fastcall TCppModelFrame::TCppModelFrame(TComponent* Owner) : TFrame(Owner)
  {
  CppModel = new TCppModelWrapper(_getFullFileName(TCppModelWrapper::LooperClfFileName) );
  InteropNegotiator negotiator;
  negotiator.report_progress = ProgressChanged;
  negotiator.message = PrintMessageMultiLine;
  negotiator.finished = Finished;
  negotiator.report_progress = ProgressChanged;
  negotiator.control_frame_handle = (CONTROL_FRAME_H)this;
  CppModel->SetNegotiator(negotiator);

  btCancel->Enabled = false;
  if (CppModel &&  CppModel->IsOk())
    {
    MemoMsg->Lines->Add("loaded");
    }
  else
    {
    MemoMsg->Lines->Add("cant'load classifier");
    DisableButtons();
    btReload->Enabled = true;
    }
  }

// ---------------------------------------------------------------------------
__fastcall TCppModelFrame::~TCppModelFrame()
  {
  delete CppModel;
  }

// ---------------------------------------------------------------------------
void __fastcall TCppModelFrame::btOptimizeWeightsClick(TObject *)
  {
  if (!CppModel->IsOk())
    return;
  CppModel->OptimizeWeights();
  DisableButtons();
  btCancel->Enabled = true;
  IsWorking = true;

  }

// ---------------------------------------------------------------------------
void __fastcall TCppModelFrame::btOptimizeParamsClick(TObject *)
  {
  if (!CppModel->IsOk())
    return;
  CppModel->OptimizeParams();
  DisableButtons();
  btCancel->Enabled = true;
  IsWorking = true;
  }

// ---------------------------------------------------------------------------
void __fastcall TCppModelFrame::btCrossValClick(TObject *)
  {
  if (!CppModel->IsOk())
    return;
  CppModel->CrossValReport();
  DisableButtons();
  btCancel->Enabled = true;
  IsWorking = true;
  }

// ---------------------------------------------------------------------------
void __fastcall TCppModelFrame::btSaveClick(TObject *)
  {
  if (CppModel->SaveTo(_getFullFileName(TCppModelWrapper::LooperClfFileName)) == 0)
    {
    MemoMsg->Lines->Add("saved");
    }
  else
    {
    MemoMsg->Lines->Add("can't save");
    }

  }

// ---------------------------------------------------------------------------
void __fastcall TCppModelFrame::btCancelClick(TObject *)
  {
  CppModel->Cancel();
  CancelPending = true;
  }

// ---------------------------------------------------------------------------
void __fastcall TCppModelFrame::btPrintClfInfoClick(TObject *)
  {
  TStringDynArray tmp = SplitString(CppModel->GetInfo(), "\n");
  for (int i = 0; i < tmp.Length; i++)
    {
    MemoMsg->Lines->Add(tmp[i]);
    }
  }
// ---------------------------------------------------------------------------

void __fastcall TCppModelFrame::btReloadClick(TObject * /* Sender */)
  {
  if (CppModel->Load(_getFullFileName(TCppModelWrapper::LooperClfFileName)) == 0)
    {
    MemoMsg->Lines->Add("loaded");
	  InteropNegotiator negotiator;
	  negotiator.report_progress = ProgressChanged;
	  negotiator.message = PrintMessageMultiLine;
	  negotiator.finished = Finished;
	  negotiator.report_progress = ProgressChanged;
	  negotiator.control_frame_handle = (CONTROL_FRAME_H)this;
	  CppModel->SetNegotiator(negotiator);
    EnableButtons();
    }
  else
    {
    MemoMsg->Lines->Add("can't load");
    }
  }
// ---------------------------------------------------------------------------
