/*
    TCFbEDataSetEx.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 TCFbEDataSetExH
#define TCFbEDataSetExH
//---------------------------------------------------------------------------
// #include "Maprof.h"

#include "math.h"
#include "TCFbEToolkit.h"
#include "TCFbETypes.h"

#include "TCFbECustomTableEx.h"

#include "TCFbETableEx.h"
#include "TCFbERotatedTableEx.h"
#include "TCFbECell.h"
#include "TCFbENeighbor.h"

#include "TCFbESimilarityComputationAlgorithm.h"
#include "TCFbEPredictionAlgorithm.h"
//---------------------------------------------------------------------------
// Facade 的なクラス
class TCFbEDataSetEx : public TCFbETableEx
{
public:
    // アクセサ
    virtual void __fastcall SetValueByIndex(int TargetRowIndex, int TargetColumnIndex, double Value) {
        TCFbETableEx::SetValueByIndex(TargetRowIndex, TargetColumnIndex, Value);
        this->RePrepareCF(TargetRowIndex, TargetColumnIndex);
    }

    virtual void __fastcall UnableElementByIndex(int TargetRowIndex, int TargetColumnIndex) {
        TCFbETableEx::UnableElementByIndex(TargetRowIndex, TargetColumnIndex);
        this->RePrepareCF(TargetRowIndex, TargetColumnIndex);
    }

    virtual bool IsPrepared(void) { // CF の準備ができていれば true，できていなければ false
        return this->FIsPrepared;
    }

    virtual TCFbETableEx* __fastcall GetNormalizedTable(void) {
//        return (TCFbETableEx*)this->GetChildCache("NormalizedTable");
        return (TCFbETableEx*)this->GetChildCacheList()->Items[0];
    }

    virtual TCFbECustomTableEx* __fastcall GetSimilarityComputationTable(void) {
//        return (TCFbECustomTableEx*)this->GetNormalizedTable()->GetChildCache("SimilarityComputationTable");
        return (TCFbECustomTableEx*)this->GetNormalizedTable()->GetChildCacheList()->Items[this->GetNormalizedTable()->GetChildCacheList()->Count - 2];
    }

    virtual TCFbECustomTableEx* __fastcall GetPredictionTable(void) {
//        return (TCFbECustomTableEx*)this->GetNormalizedTable()->GetChildCache("PredictionTable");
        return (TCFbECustomTableEx*)this->GetNormalizedTable()->GetChildCacheList()->Items[this->GetNormalizedTable()->GetChildCacheList()->Count - 1];
    }

    virtual TCFbERowRowCachedTable* __fastcall GetSimilarityCache(void) {
//        return (TCFbERowRowCachedTable*)this->GetSimilarityComputationTable()->GetChildCache("SimilarityCache");
        return (TCFbERowRowCachedTable*)this->GetSimilarityComputationTable()->GetChildCacheList()->Items[0];
    }

    virtual TCFbECustomTableEx* __fastcall GetPredictedValueCache(void) {
//        return (TCFbECustomTableEx*)this->GetPredictionTable()->GetChildCache("PredictedValueCache");
        return (TCFbECustomTableEx*)this->GetPredictionTable()->GetChildCacheList()->Items[0];
    }

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

    virtual double __fastcall GetPredictedValue(const char* TargetRowLabel, const char* 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 TCFbEDataSetEx(void);   // コンストラクタ
    virtual __fastcall TCFbEDataSetEx(TStringList* SourceCsvStringList); // コンストラクタ
    __fastcall ~TCFbEDataSetEx();    // デストラクタ

    virtual void __fastcall InitCache(void);    // キャッシュを初期化する

    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 void __fastcall GetNearestNeighbors(int TargetRowIndex, int TargetColumnIndex, int NeighborhoodSize, TObjectList* NeighborList);    // TargetRowIndex に対する NearestNeigobors を調べる

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

    virtual double  __fastcall DisOrderingEx(int ColumnIndex, double Order);  // ColumnIndex 列目の Ordering された値 Order を DisOrdering して返す

    virtual void    __fastcall TemporallyUnable(int TargetRowIndex, int TargetColumnIndex); // TargetRowIndex, TargetColumnIndex のセルを一時的に Enabled = false にする
    virtual void    __fastcall RecoverEnabled(void);    // 一時的に Enabled = false にしていたセルを元にもどす

protected:
    virtual void __fastcall RePrepareCF(int TargetRowIndex, int TargetColumnIndex);
    virtual void __fastcall CellIsUpdatedByIndex(int RowIndex, int ColumnIndex) {
        if (this->IsPrepared()) {
            TCFbETableEx::CellIsUpdatedByIndex(RowIndex, ColumnIndex);
        }
    }

    TCFbEValueBase      FValueBase;
    TCFbEAlgorithmBase  FAlgorithmBase;
    TCFbESimilarityComputationAlgorithm*    FSimilarityComputationAlgorithm;
    TCFbEPredictionAlgorithm*               FPredictionAlgorithm;
    int     FNeighborhoodSize;
    bool    FDefaultValueEnabled;
    double  FDefaultValue;
    bool    FInverseCaseFrequencyEnabled;
    double  FCaseAmplifier;
    bool    FIsPrepared;

    int     TemporallyUnableRowIndex;
    int     TemporallyUnableColumnIndex;
    double  TemporallyUnableValue;

private:

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