/*
    TCFbETable.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 TCFbETableH
#define TCFbETableH
//---------------------------------------------------------------------------
#include <System.hpp>
#include <Classes.hpp>
#include <Contnrs.hpp>

// #include "Maprof.h"

#include "TCFbECell.h"
#include "TCFbEToolkit.h"
#include "TCFbEPrimitiveTable.h"
//---------------------------------------------------------------------------
class TCFbETable : public TCFbEPrimitiveTable
{
public:
    // アクセサメソッド
    virtual void __fastcall SetValueByIndex(int TargetRowIndex, int TargetColumnIndex, double Value) {
        TCFbECell* Cell = this->GetCellByIndex(TargetRowIndex, TargetColumnIndex);
        if (!Cell->GetEnabled() || Cell->GetValue() != Value) {
            Cell->SetValue(Value);
            this->RowIsUpdated(TargetRowIndex);
            this->ColumnIsUpdated(TargetColumnIndex);
        }
    }

    virtual void __fastcall SetEnabledByIndex(int TargetRowIndex, int TargetColumnIndex, bool Value) {
        TCFbECell* Cell = this->GetCellByIndex(TargetRowIndex, TargetColumnIndex);
        if (Cell->GetEnabled() != Value) {
            Cell->SetEnabled(Value);
            this->RowIsUpdated(TargetRowIndex);
            this->ColumnIsUpdated(TargetColumnIndex);
        }
    }


    virtual void __fastcall SetCell(AnsiString RowLabel, AnsiString ColumnLabel, TCFbECell* Cell) {
        this->SetCellByIndex(this->RowIsUpdated(RowLabel), this->ColumnIsUpdated(ColumnLabel), Cell);
    }

    virtual void __fastcall SetCellByIndex(int RowIndex, int ColumnIndex, TCFbECell* Cell) {
        this->RowIsUpdated(RowIndex);
        this->ColumnIsUpdated(ColumnIndex);
        TCFbEPrimitiveTable::SetCellByIndex(RowIndex, ColumnIndex, Cell);
    }

    virtual __fastcall      TCFbETable(void);       // コンストラクタ（空のテーブルを作成
    virtual __fastcall      TCFbETable(TStringList* RowLabelList, TStringList* ColumnLabelList);    // 指定された行列を備えた空テーブルを作成
    __fastcall              ~TCFbETable();          // デストラクタ

    virtual void __fastcall RowIsUpdated(int RowIndex);
    virtual int __fastcall  RowIsUpdated(AnsiString RowLabel);
    virtual void __fastcall ColumnIsUpdated(int  ColumnIndex);
    virtual int __fastcall  ColumnIsUpdated(AnsiString ColumnLabel);

    // 行を削除する．
    virtual void __fastcall DeleteRowByIndex(int TargetRowIndex) {
        TCFbEPrimitiveTable::DeleteRowByIndex(TargetRowIndex);
        this->DeleteRowCache(TargetRowIndex);
    }

    // 列を削除する．
    virtual void __fastcall DeleteColumnByIndex(int TargetColumnIndex) {
        TCFbEPrimitiveTable::DeleteColumnByIndex(TargetColumnIndex);
        this->DeleteColumnCache(TargetColumnIndex);
    }

    // 行を追加する．
    virtual int __fastcall AddRow(AnsiString RowLabel) {
        this->AddRowCache();
        return TCFbEPrimitiveTable::AddRow(RowLabel);
    }

    // 列を追加する．
    virtual int __fastcall AddColumn(AnsiString ColumnLabel) {
        this->AddColumnCache();
        return TCFbEPrimitiveTable::AddColumn(ColumnLabel);
    }

    virtual void __fastcall Assign(TCFbETable* SourceTable);            // SourceTable の各要素をコピーする
    virtual void __fastcall AssignWithTurn(TCFbETable* SourceTable);    // SourceTable の各要素の行と列を入替えてコピーする

    virtual bool __fastcall Normalize(TCFbECell* Cell, double MaxValue, double MinValue);    // Normalize する
    virtual void __fastcall PartialNormalize(int ColumnIndex, bool RowUpdate=true); // Table の要素を部分的に Normalize する
    virtual void __fastcall Normalize(void);        // Table の要素を Normalize する

    virtual bool __fastcall Standardize(TCFbECell* Cell, double AverageValue, double StdevValue);   // Standardize する
    virtual void __fastcall PartialStandardize(int ColumnIndex, bool RowUpdate=true); // Table の要素を部分的に Standardize する
    virtual void __fastcall Standardize(void);    // Table の要素を Standardize する

    virtual void __fastcall Ordering(TList* SortedCellList);    // Ordering する
    virtual void __fastcall PartialOrdering(int ColumnIndex, bool RowUpdate=true); // Table の要素を部分的に Ordering する
    virtual void __fastcall Ordering(void);    // Table の要素を Ordering する

    virtual void __fastcall PartialRowNormalize(int RowIndex, bool ColumnUpdate=true); // Table の要素を横方向に部分的に Normalize する
    virtual void __fastcall PartialRowNormalizeOnColumn(int ColumnIndex, bool RowUpdate=true);  // ColumnIndex 番目の列の Table の要素を横方向に部分的に Normalize する
    virtual void __fastcall RowNormalize(void);    // Table の要素を横方向に Normalize する
    virtual void __fastcall PartialRowStandardize(int RowIndex, bool ColumnUpdate=true); // Table の要素を横方向に部分的に Standardize する
    virtual void __fastcall PartialRowStandardizeOnColumn(int ColumnIndex, bool RowUpdate=true); // ColumnIndex 番目の列の Table の要素を横方向に部分的に Standardize する
    virtual void __fastcall RowStandardize(void);    // Table の要素を横方向に Standardize する
    // Ordering は部分的にやっても効率が良くなさそう
    virtual void __fastcall PartialRowOrdering(int RowIndex, bool ColumnUpdate=true); // Table の要素を横方向に部分的に Ordering する
    virtual void __fastcall RowOrdering(void);    // Table の要素を横方向に Ordering する

    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, TDoubleDynArray& SortedOrders);    // ColumnIndex 列目の Ordering された値 Order を DisOrdering して返す

    virtual double __fastcall   DisRowNormalize(int RowIndex, double RowNormalizedValue);    // RowIndex 列目の横方向に Normalize された値 RowNormalizedValue を DisRowNormalize して返す
    virtual double __fastcall   DisRowStandardize(int RowIndex, double RowStandardizedValue);    // RowIndex 列目の横方向に Standardize された値 RowStandardizedValue を DisRowStandardize して返す
    virtual double __fastcall   DisRowOrdering(int RowIndex, double RowOrder, TDoubleDynArray& SortedOrders);    // RowIndex 列目の横方向に Ordering された値 RowOrder を DisRowOrdering して返す

    virtual double __fastcall   DisOrderingCommon(int Index, double Order, TDoubleDynArray& SortedOrders, TDoubleDynArray& SortedValues);    // DisOrdering と DisRowOrdering で使う共通の処理

    virtual double __fastcall   GetMaxOfRow(int i);    // 行の最大値を返す．
    virtual double __fastcall   GetMinOfRow(int i);    // 行の最小値を返す．
    virtual double __fastcall   GetAverageOfRow(int i);    // 行の平均値を返す．
    virtual double __fastcall   GetMedianOfRow(int i);    // 行の中間値を返す．
    virtual double __fastcall   GetStdevOfRow(int i);    // 行の標準偏差を返す．
    virtual double __fastcall   GetInversedDistanceOfRow(int BaseRowIndex, int ComparedRowIndex);    // ComparedRowIndex 番目の行の BaseRowIndex 番目の行に対する Inversed Distance を返す．
    virtual double __fastcall   GetAveragedMultiplierOfRow(int BaseRowIndex, int ComparedRowIndex);    // ComparedRowIndex 番目の行の BaseRowIndex 番目の行に対する Averaged Multiplier を返す．
    virtual double __fastcall   GetMedianOfMultiplierOfRow(int BaseRowIndex, int ComparedRowIndex);    // ComparedRowIndex 番目の行の BaseRowIndex 番目の行に対する Median of Multiplier を返す．
    virtual double __fastcall   GetWeightedMultiplierOfRow(int BaseRowIndex, int ComparedRowIndex, int BaseColumnIndex);    // BaseColumnIndex 番目の列に関する ComparedRowIndex 番目の行の BaseRowIndex 番目の行に対する Weighted Multiplier を返す．

    virtual double __fastcall   GetMaxOfColumn(int j);    // 列の最大値を返す．
    virtual double __fastcall   GetMinOfColumn(int j);    // 列の最小値を返す．
    virtual double __fastcall   GetAverageOfColumn(int j);    // 列の平均値を返す．
    virtual double __fastcall   GetMedianOfColumn(int j);    // 列の中間値を返す．
    virtual double __fastcall   GetStdevOfColumn(int j);    // 列の標準偏差を返す．
    virtual double __fastcall   GetInversedDistanceOfColumn(int BaseColumnIndex, int ComparedColumnIndex);    // BaseColumnIndex 番目の列の ComparedColumnIndex 番目の列に対する Inversed Distance を返す．
    virtual double __fastcall   GetAveragedMultiplierOfColumn(int BaseColumnIndex, int ComparedColumnIndex);    // BaseColumnIndex 番目の列の ComparedColumnIndex 番目の列に対する Averaged Multiplier を返す．
    virtual double __fastcall   GetMedianOfMultiplierOfColumn(int BaseColumnIndex, int ComparedColumnIndex);    // BaseColumnIndex 番目の列の ComparedColumnIndex 番目の列に対する Median of Multiplier を返す．
    virtual double __fastcall   GetWeightedMultiplierOfColumn(int BaseColumnIndex, int ComparedColumnIndex, int BaseRowIndex);    // BaseRowIndex 番目の行に関する BaseColumnIndex 番目の列の ComparedColumnIndex 番目の列に対する Weighted Multiplier を返す．

protected:
    virtual void __fastcall AddRowCache(void);       // 行方向のキャッシュを追加する
    virtual void __fastcall AddColumnCache(void);    // 列方向のキャッシュを追加する
    virtual void __fastcall DeleteRowCache(int TargetRowIndex);         // 行方向のキャッシュを削除する
    virtual void __fastcall DeleteColumnCache(int TargetColumnIndex);   // 列方向のキャッシュを削除する
    virtual void __fastcall CopyRowCache(TCFbETable* SourceTable, int TargetRowIndex);          // 行方向のキャッシュをコピーする
    virtual void __fastcall CopyColumnCache(TCFbETable* SourceTable, int TargetColumnIndex);    // 列方向のキャッシュをコピーする
    virtual void __fastcall CopyRowCacheFromColumn(TCFbETable* SourceTable, int TargetRowIndex);    // 行方向のキャッシュを列方向のキャッシュからコピーする
    virtual void __fastcall CopyColumnCacheFromRow(TCFbETable* SourceTable, int TargetColumnIndex); // 列方向のキャッシュを行方向のキャッシュからコピーする

    TObjectList*    MaxOfRowList;
    TObjectList*    MinOfRowList;
    TObjectList*    AverageOfRowList;
    TObjectList*    MedianOfRowList;
    TObjectList*    StdevOfRowList;
    TObjectList*    InversedDistanceOfRowList;
    TList*          CachedBaseRowListForID;

    TObjectList*    MaxOfColumnList;
    TObjectList*    MinOfColumnList;
    TObjectList*    AverageOfColumnList;
    TObjectList*    MedianOfColumnList;
    TObjectList*    StdevOfColumnList;
    TObjectList*    InversedDistanceOfColumnList;
    TList*          CachedBaseColumnListForID;

private:

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