/*
    TCFbEPrimitiveTable.h    November 26, 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 TCFbEPrimitiveTableH
#define TCFbEPrimitiveTableH
//---------------------------------------------------------------------------
#include <System.hpp>
#include <Classes.hpp>
#include <Contnrs.hpp>

// #include "Maprof.h"

#include "TCFbECell.h"
#include "TCFbEToolkit.h"
//---------------------------------------------------------------------------
class TCFbEPrimitiveTable : public TObject
{
public:
    // アクセサメソッド
    virtual int __fastcall GetNumberOfRows(void) {
        return this->FRowLabelList->Count;
    }

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

    virtual double __fastcall GetValueByIndex(int TargetRowIndex, int TargetColumnIndex) {
        return this->GetCellByIndex(TargetRowIndex, TargetColumnIndex)->GetValue();
    }

    virtual void __fastcall SetValueByIndex(int TargetRowIndex, int TargetColumnIndex, double Value) {
        this->GetCellByIndex(TargetRowIndex, TargetColumnIndex)->SetValue(Value);
    }

    virtual bool __fastcall GetEnabledByIndex(int TargetRowIndex, int TargetColumnIndex) {
        return this->GetCellByIndex(TargetRowIndex, TargetColumnIndex)->GetEnabled();
    }

    virtual void __fastcall SetEnabled(AnsiString RowLabel, AnsiString ColumnLabel, bool Value) {
        this->SetEnabledByIndex(this->FRowLabelList->IndexOf(RowLabel), this->FColumnLabelList->IndexOf(ColumnLabel), Value);
    }

    virtual void __fastcall SetEnabledByIndex(int TargetRowIndex, int TargetColumnIndex, bool Value) {
        this->GetCellByIndex(TargetRowIndex, TargetColumnIndex)->SetEnabled(Value);
    }

    virtual TCFbECell* __fastcall GetCell(AnsiString RowLabel, AnsiString ColumnLabel) {
        return this->GetCellByIndex(this->FRowLabelList->IndexOf(RowLabel), this->FColumnLabelList->IndexOf(ColumnLabel));
    }

    virtual TCFbECell* __fastcall GetCellByIndex(int RowIndex, int ColumnIndex) {
        return (TCFbECell*)((TObjectList*)this->RowList->Items[RowIndex])->Items[ColumnIndex];
    }

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

    virtual void __fastcall SetCellByIndex(int RowIndex, int ColumnIndex, TCFbECell* Cell) {
        TCFbECell* TargetCell = (TCFbECell*)((TObjectList*)this->RowList->Items[RowIndex])->Items[ColumnIndex];
        if (TargetCell != NULL) {
            delete TargetCell;
        }
        ((TObjectList*)this->RowList->Items[RowIndex])->Items[ColumnIndex] = Cell;
    }

    virtual TStringList* __fastcall GetRowLabelList(void) { return this->FRowLabelList; }
    virtual TStringList* __fastcall GetColumnLabelList(void) { return this->FColumnLabelList; }

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

    // 行を削除する．
    virtual void __fastcall DeleteRow(AnsiString RowLabel) {
        int TargetRowIndex = this->FRowLabelList->IndexOf(RowLabel);
        if (TargetRowIndex < 0) {
            throw Exception("The row named \"" + RowLabel + "\" was not existing.");
        }
        this->DeleteRowByIndex(TargetRowIndex);
    }

    // 行を削除する．
    virtual void __fastcall DeleteRowByIndex(int TargetRowIndex) {
        this->FRowLabelList->Delete(TargetRowIndex);
        this->RowList->Delete(TargetRowIndex);
    }

    // 列を削除する．
    virtual void __fastcall DeleteColumn(AnsiString ColumnLabel) {
        int TargetColumnIndex = this->FColumnLabelList->IndexOf(ColumnLabel);
        if (TargetColumnIndex < 0) {
            throw Exception("The column named \"" + ColumnLabel + "\" was not existing.");
        }
        this->DeleteColumnByIndex(TargetColumnIndex);
    }

    // 列を削除する．
    virtual void __fastcall DeleteColumnByIndex(int TargetColumnIndex) {
        this->FColumnLabelList->Delete(TargetColumnIndex);
        for (int i = 0; i < this->GetNumberOfRows() ; i++) {
            ((TObjectList*)this->RowList->Items[i])->Delete(TargetColumnIndex);
        }
    }

    virtual int __fastcall  AddRow(AnsiString RowLabel);    // 行を追加する．
    virtual int __fastcall  AddColumn(AnsiString ColumnLabel);    // 列を追加する．

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

    virtual int __fastcall  CopyRowFrom(TCFbEPrimitiveTable* SourceTable, int SourceRowIndex, bool AddColumn = true);    // SourceTable の SourceRowIndex 行目をコピーする
    virtual int __fastcall  CopyRowAsColumnFrom(TCFbEPrimitiveTable* SourceTable, int SourceRowIndex, bool AddRow = true);    // SourceTable の SourceRowIndex 行目を列としてコピーする
    virtual int __fastcall  CopyColumnFrom(TCFbEPrimitiveTable* SourceTable, int SourceColumnIndex, bool AddRow);  // SourceTable の SourceColumnIndex 列目をコピーする
    virtual int __fastcall  CopyColumnAsRowFrom(TCFbEPrimitiveTable* SourceTable, int SourceColumnIndex, bool AddColumn);  // SourceTable の SourceColumnIndex 列目を列としてコピーする

    virtual int __fastcall  GetEnabledCountOfRow(int i);    // 列で Enabled なセルの数を返す
    virtual int __fastcall  GetEnabledCountOfColumn(int j);    // 列で Enabled なセルの数を返す
    virtual void __fastcall GetBothEnableSortedCellList(int TargetRowIndex, int ComparedRowIndex, TList* TargetSortedCellList, TList* ComparedSortedCellList);    // TargetRowIndex 行目と ComparedRowIndex 行目で共通して Enabled な要素をソートし，TargetSortedCellList と　ComparedSortedCellList にそれぞれ入れて返す（RankCorrelation で使われる

    virtual void __fastcall GetSortedCellListOfRow(int RowIndex, TList* SortedCellList);    // RowIndex 番目の行の Enabled な要素をソートし，SortedCellList に入れて返す
    virtual void __fastcall GetSortedCellListOfColumn(int ColumnIndex, TList* SortedCellList);    // ColumnIndex 番目の列の Enabled な要素をソートし，SortedCellList に入れて返す

protected:
    virtual void __fastcall GetEnabledCellsInRow(int RowIndex, TDoubleDynArray& DynArray);    // RowIndex 番目の行の Enabled な要素を DynArray に入れて返す
    virtual void __fastcall GetEnabledCellsInColumn(int ColumnIndex, TDoubleDynArray& DynArray);    // ColumnIndex 番目の列の Enabled な要素を DynArray に入れて返す

    TStringList*    FRowLabelList;
    TStringList*    FColumnLabelList;

    TObjectList*    RowList;

private:

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