/*
    TCFbEDataSet.h    June 6, 2004.

    Copyright (C) 2003-2004 CFbE Research Group,
    Software Engineering Laboratory,
    Graduate School of Information Science,
    Nara Institute of Science and Technology,
    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, (at your option) or
    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 GNU Emacs; see the file COPYING.  If not, write to the
    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/
//---------------------------------------------------------------------------
#ifndef TCFbEDataSetH
#define TCFbEDataSetH
//---------------------------------------------------------------------------
// #include "Maprof.h"

#include "math.h"
#include "TCFbEToolkit.h"
#include "TCFbETable.h"
#include "TCFbECell.h"
#include "TCFbENeighbor.h"

class TCFbESimilarityComputationAlgorithm;
#include "TCFbESimilarityComputationAlgorithm.h"

class TCFbEPredictionAlgorithm;
#include "TCFbEPredictionAlgorithm.h"
//---------------------------------------------------------------------------
// 準備されている値
enum TCFbEValueBase { vbUnknown, vbValue, vbStandardizedValue, vbNormalizedValue, vbOrder, vbDoubleStandardizedValue, vbDoubleNormalizedValue, vbDoubleOrder };

// 何ベースのアルゴリズムか（abUnknown なら abRow と同様だとみなす
enum TCFbEAlgorithmBase { abUnknown, abRow, abColumn };
//---------------------------------------------------------------------------
// Facade 的なクラス
class TCFbEDataSet : public TObject
{
public:
    // アクセサ
    virtual double __fastcall GetSourceValue(AnsiString RowLabel, AnsiString ColumnLabel) {
        return this->FSourceTable->GetCell(RowLabel, ColumnLabel)->GetValue();
    }

    virtual void __fastcall SetSourceValue(AnsiString RowLabel, AnsiString ColumnLabel, double Value) {
        this->IsUpdated();
        this->FSourceTable->GetCellByIndex(this->FSourceTable->RowIsUpdated(RowLabel), this->FSourceTable->ColumnIsUpdated(ColumnLabel))->SetValue(Value);
    }

    virtual double __fastcall GetValueByIndex(int RowIndex, int ColumnIndex) {
        return this->FSourceTable->GetCellByIndex(RowIndex, ColumnIndex)->GetValue();
    }

    virtual void __fastcall SetValuesByIndex(int RowIndex, int ColumnIndex, double Value) {
        this->IsUpdated();
        this->FSourceTable->RowIsUpdated(RowIndex);
        this->FSourceTable->ColumnIsUpdated(ColumnIndex);
        this->FSourceTable->GetCellByIndex(RowIndex, ColumnIndex)->SetValue(Value);
    }

    virtual bool __fastcall GetEnabled(AnsiString RowLabel, AnsiString ColumnLabel) {
        return this->FSourceTable->GetCell(RowLabel, ColumnLabel)->GetEnabled();
    }

    virtual void __fastcall SetEnabled(AnsiString RowLabel, AnsiString ColumnLabel, bool Value) {
        this->IsUpdated();
        this->FSourceTable->GetCellByIndex(this->FSourceTable->RowIsUpdated(RowLabel), this->FSourceTable->ColumnIsUpdated(ColumnLabel))->SetEnabled(Value);
    }

    virtual bool __fastcall GetEnabledByIndex(int RowIndex, int ColumnIndex) {
        return this->FSourceTable->GetCellByIndex(RowIndex, ColumnIndex)->GetEnabled();
    }

    virtual void __fastcall SetEnabledByIndex(int RowIndex, int ColumnIndex, bool Value) {
        this->IsUpdated();
        this->FSourceTable->RowIsUpdated(RowIndex);
        this->FSourceTable->ColumnIsUpdated(ColumnIndex);
        this->FSourceTable->GetCellByIndex(RowIndex, ColumnIndex)->SetEnabled(Value);
    }

    virtual int __fastcall GetNumberOfRows(void) {
        return this->FSourceTable->GetNumberOfRows();
    }

    virtual int __fastcall GetNumberOfColumns(void) {
        return this->FSourceTable->GetNumberOfColumns();
    }

    virtual TStringList* __fastcall GetRowLabelList(void) {
        return this->FSourceTable->GetRowLabelList();
    }

    virtual TStringList* __fastcall GetColumnLabelList(void) {
        return this->FSourceTable->GetColumnLabelList();
    }

    virtual TCFbETable* __fastcall GetSimilarityComputationTable(void) {
        if (!this->FAppliedTableArePrepared) {
            Exception("AppliedValues are not prepared.");
        }
        return this->FSimilarityComputationTable;
    }

    virtual TCFbETable* __fastcall GetPredictionTable(void) {
        if (!this->FAppliedTableArePrepared) {
            Exception("AppliedValues are not prepared.");
        }
        return this->FPredictionTable;
    }

    virtual double __fastcall GetSimilarity(AnsiString TargetRowLabel, AnsiString ComparedRowLabel) {
        return this->GetSimilarityByIndex(this->GetRowLabelList()->IndexOf(TargetRowLabel), this->GetRowLabelList()->IndexOf(ComparedRowLabel));
    }

    virtual double __fastcall GetPredictedValue(AnsiString TargetRowLabel, AnsiString TargetColumnLabel) {
        return this->GetPredictedValueByIndex(this->GetRowLabelList()->IndexOf(TargetRowLabel), this->GetColumnLabelList()->IndexOf(TargetColumnLabel));
    }

    virtual double __fastcall GetSimilarityByIndex(int TargetRowIndex, int ComparedRowIndex);
    virtual double __fastcall GetPredictedValueByIndex(int TargetRowIndex, int TargetColumnIndex);

    virtual TCFbESimilarityComputationAlgorithm*    GetSimilarityComputationAlgorithm(void) { return this->FSimilarityComputationAlgorithm; }
    virtual TCFbEPredictionAlgorithm*               GetPredictionAlgorithm(void) { return this->FPredictionAlgorithm; }

    
    virtual __fastcall TCFbEDataSet(void);    // コンストラクタ
    virtual __fastcall TCFbEDataSet(TStringList* SourceCsvStringList);    // コンストラクタ
    __fastcall ~TCFbEDataSet();    // デストラクタ

    virtual void    __fastcall PrepareCF(TCFbEValueBase ValueBase, TCFbEAlgorithmBase AlgorithmBase, TCFbESimilarityComputationAlgorithm* SimilarityComputationAlgorithm, TCFbEPredictionAlgorithm* PredictionAlgorithm, int NeighborhoodSize, bool DefaultValueEnabled, double DefaultValue, bool InverseCaseFrequencyEnabled, double CaseAmplifier);    // CF の準備を行う（PredictionTable を準備する
    virtual bool    __fastcall TemporaryChangeEnabled(int TargetRowIndex, int TargetColumnIndex, bool Value);   // TargetRowIndex 行目，TargetColumnIndex 列目のセルの Enabled を一時的に Value にする
    virtual void    __fastcall TemporaryUnable(int TargetRowIndex, int TargetColumnIndex);    // TargetRowIndex, TargetColumnIndex のセルを一時的に Enabled = false にする
    virtual void    __fastcall RecoverEnabled(void);    // 一時的に Enabled = false にしていたセルを元にもどす

    virtual void    __fastcall DeleteValue(AnsiString RowLabel, AnsiString ColumnLabel);    // RowLabel, ColumnLabel のセルを削除する（Enabled = false にする

    virtual int     __fastcall CopyRowFrom(TCFbEDataSet* SourceDataSet, int SourceRowIndex, bool AddColumn=true);    // DataSet の RowIndex 行目を更新する
    virtual int     __fastcall AddRow(AnsiString RowLabel);    // 行を追加する．
    virtual void    __fastcall DeleteRow(AnsiString RowLabel);    // 行を削除する．
    virtual int     __fastcall AddColumn(AnsiString ColumnLabel);    // 列を追加する．
    virtual void    __fastcall DeleteColumn(AnsiString ColumnLabel);    // 列を削除する．

    virtual double  __fastcall GetICFCoefficient(int j);    // j 列目の Inverse Case Frequency Coefficient を得る
    virtual void __fastcall GetNearestNeighbors(int TargetRowIndex, int TargetColumnIndex, int NeighborhoodSize, TObjectList* NeighborList);    // TargetRowIndex に対する NearestNeigobors を調べる

    virtual void    __fastcall FillColumns(TCFbEDataSet* BaseDataSet);    // BaseDataSet にあって，this にない列を新たな列として追加する
    virtual bool    __fastcall IsConsistentWith(TCFbEDataSet* TargetDataSet);    // TargetDataSet と首尾一貫性があるかどうかを調べる

    virtual double  __fastcall DisNormalize(int ColumnIndex, double NormalizedValue);    // ColumnIndex 列目の Normalize された値 NormalizedValue を DisNormalize して返す
    virtual double  __fastcall DisStandardize(int ColumnIndex, double StandardizedValue);    // ColumnIndex 列目の Standardize された値 StandardizedValue を DisStandardize して返す
    virtual double  __fastcall DisOrdering(int ColumnIndex, double Order);    // ColumnIndex 列目の Ordering された値 Order を DisOrdering して返す
    virtual double  __fastcall DisDoubleNormalize(int RowIndex, int ColumnIndex, double DoubleNormalizedValue);    // RowIndex 行目，ColumnIndex 列目の DoubleNormalize された値 DoubleNormalizedValue を DisDoubleNormalize して返す
    virtual double  __fastcall DisDoubleStandardize(int RowIndex, int ColumnIndex, double DoubleStandardizedValue);    // RowIndex 行目，ColumnIndex 列目の DoubleStandardize された値 DoubleStandardizedValue を DisDoubleStandardize して返す
    virtual double  __fastcall DisDoubleOrdering(int RowIndex, int ColumnIndex, double DoubleOrder);    // RowIndex 行目，ColumnIndex 列目の DoubleOrdering された値 DoubleOrder を DisDoubleOrdering して返す

protected:
    TCFbEValueBase      FValueBase;
    TCFbEAlgorithmBase  FAlgorithmBase;
    TCFbETable*         FSourceTable;
    TCFbETable*         FSimilarityComputationTable;
    TCFbETable*         FPredictionMediateTable;
    TCFbETable*         FPredictionTable;
    bool                FAppliedTableArePrepared;
    TCFbESimilarityComputationAlgorithm*    FSimilarityComputationAlgorithm;
    TCFbEPredictionAlgorithm*               FPredictionAlgorithm;
    int                 FNeighborhoodSize;
    bool                FDefaultValueEnabled;
    double              FDefaultValue;
    bool                FInverseCaseFrequencyEnabled;
    double              FCaseAmplifier;
    TObjectList*        FSimilarityList;
    int                 TargetRowIndexOfSimilarity;
    TObjectList*        FPredictedValueList;
    int                 TargetRowIndexOfPrediction;
    int                 TemporaryUnableRowIndex;
    int                 TemporaryUnableColumnIndex;

    // アップデートされたことをマークし，キャッシュをクリアする
    virtual void __fastcall IsUpdated(void) {
        this->FAppliedTableArePrepared = false;
        this->TargetRowIndexOfSimilarity = -1;
        this->TargetRowIndexOfPrediction = -1;
    }

    virtual void __fastcall CsvToStrings2(char* str, TStrings *List);    // CSV形式の文字列をTStringsに分解する

private:

};
//---------------------------------------------------------------------------
#endif
