/*
    TCFbEOutputCache.h    June 6, 2004.

    Copyright (C) 2003-2005 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 TCFbEOutputCacheH
#define TCFbEOutputCacheH
//---------------------------------------------------------------------------
#include <system.hpp>
#include <Classes.hpp>
#include <stdio.h>
#include <Math.hpp>

#include "EDocfbeError.h"

#include "TCFbEDataSetEx.h"
#include "TCFbEDocfbeCommandLineParser.h"
#include "TCFbEDocfbeDataLoader.h"

#include "TCFbERowColumnCachedTable.h"
//---------------------------------------------------------------------------
class TCFbEOutputCache : public TObject
{
public:
    virtual __fastcall TCFbEOutputCache(TCFbEDocfbeCommandLineParser* Parser, TCFbEDocfbeDataLoader* DataLoader, bool IsVerbose=false);    // コンストラクタ
    __fastcall ~TCFbEOutputCache();    // デストラクタ

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

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

    virtual AnsiString __fastcall GetResultRowLabel(int RowIndex);
    virtual AnsiString __fastcall GetResultColumnLabel(int ColumnIndex);

    // ColumnIndex 列目に結果が出力されているかどうかを調べる
    virtual bool __fastcall IsResultedColumn(int ColumnIndex) {
        return this->FIsResultedColumn[ColumnIndex];
    }

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

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

    virtual bool __fastcall GetResultFailed(int RowIndex, int ColumnIndex) {
        return this->FResultTable->GetCellByIndex(RowIndex, ColumnIndex)->GetRank() == 0.0;
    }

    virtual int __fastcall GetNumberOfNeighbors(int TargetIndex) {
        return ((TObjectList*)this->FNeighborsList->Items[TargetIndex])->Count;
    }

    virtual TCFbENeighbor* __fastcall GetNeighbor(int TargetIndex, int NeighborsIndex) {
        return (TCFbENeighbor*)((TObjectList*)this->FNeighborsList->Items[TargetIndex])->Items[NeighborsIndex];
    }

    virtual int __fastcall GetDistribution(int TargetIndex, int RangeIndex) {
        return (int)((TList*)this->FDistributionList->Items[TargetIndex])->Items[RangeIndex];
    }

    int    ErrorCode;    // エラーコード（エラーがない場合は 0
    AnsiString    ErrorParameter;    // エラーパラメータ

protected:
    virtual void __fastcall CountDistribution(TCFbEDataSetEx* DataSet, int TargetRowIndex, TList* StoredList);    // DataSet における TargetRowIndex 行目の行に対する類似度の分布を StoredList に格納して返す

    // コンストラクタでの計算で用いるメソッド，TargetRowIndex を得る
    virtual int __fastcall GetTargetRowIndex(TCFbEDataSetEx* LearningData, TCFbEDataSetEx* EstimatingData, int i) {
        return (EstimatingData == LearningData) ? i : LearningData->CopyRowFrom(EstimatingData, i, false);
    }

    // コンストラクタでの計算で用いるメソッド，TargetColumnIndex を得る
    virtual int __fastcall GetTargetColumnIndex(TCFbEDataSetEx* LearningData, TCFbERowColumnCachedTable* ResultTable, int j) {
        return LearningData->GetColumnLabelList()->IndexOf(ResultTable->GetColumnLabelList()->Strings[j]);
    }

    virtual void __fastcall PredictionBody(TCFbECell* Result, TCFbEDataSetEx* LearningData, int TargetRowIndex, int TargetColumnIndex); // コンストラクタでの計算で用いるメソッド，Result に予測値を設定する
    virtual void __fastcall GetNeighborsInformation(TObjectList* NeighborsList, TObjectList* DistributionList, TCFbEDataSetEx* LearningData, int TargetRowIndex, int TargetColumnIndex, TCFbEAlgorithmBase AlgorithmBase, int NeighborsSize);   // コンストラクタでの計算で用いるメソッド，NearestNeighbors と類似度の分布を調べる

    TCFbEDocfbeCommandLineParser*   Parser;
    TCFbEDocfbeDataLoader*          DataLoader;
    TCFbERowColumnCachedTable*      FResultTable;   // 計算結果を格納するテーブル
    TObjectList*        FNeighborsList;             // NearestNeighbors を格納する TObjectList を格納するための TObjectList
    TObjectList*        FDistributionList;          // 類似度の分布を格納する TList を格納するための TObjectList
    TBooleanDynArray    FIsResultedColumn;          // 各列に出力された値があるか

private:

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