/*
    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 <IniFiles.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 GetValue(const char* TargetRowLabel, const char* TargetColumnLabel) {
        return this->GetValueByIndex(this->GetRowLabelList()->IndexOf(TargetRowLabel), this->GetColumnLabelList()->IndexOf(TargetColumnLabel));
    }

    virtual bool __fastcall GetEnabled(const char* TargetRowLabel, const char* TargetColumnLabel) {
        return this->GetEnabledByIndex(this->GetRowLabelList()->IndexOf(TargetRowLabel), this->GetColumnLabelList()->IndexOf(TargetColumnLabel));
    }

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

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

    virtual void __fastcall SetValue(const char* TargetRowLabel, const char* TargetColumnLabel, double Value) {
        this->SetValueByIndex(this->GetRowLabelList()->IndexOf(TargetRowLabel), this->GetColumnLabelList()->IndexOf(TargetColumnLabel), Value);
    }

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

    virtual void __fastcall UnableElement(const char* RowLabel, const char* ColumnLabel) {
        this->UnableElementByIndex(this->FRowLabelList->IndexOf(RowLabel), this->FColumnLabelList->IndexOf(ColumnLabel));
    }

    virtual void __fastcall UnableElementByIndex(int TargetRowIndex, int TargetColumnIndex) {
        this->GetCellByIndex(TargetRowIndex, TargetColumnIndex)->SetEnabled(false);
    }

    virtual TCFbECell* __fastcall GetCell(const char* RowLabel, const char* 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(const char* RowLabel, const char* 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);    // 指定された行列を備えた空テーブルを作成
    virtual __fastcall TCFbEPrimitiveTable(TStringList* SourceCsvStringList);   // コンストラクタ
    __fastcall ~TCFbEPrimitiveTable();     // デストラクタ

    // 行を削除する．
    virtual void __fastcall DeleteRow(const char* RowLabel) {
        int TargetRowIndex = this->FRowLabelList->IndexOf(RowLabel);
        if (TargetRowIndex < 0) {
            throw Exception("The row named \"" + AnsiString(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(const char* ColumnLabel) {
        int TargetColumnIndex = this->FColumnLabelList->IndexOf(ColumnLabel);
        if (TargetColumnIndex < 0) {
            throw Exception("The column named \"" + AnsiString(ColumnLabel) + "\" was not existing.");
        }
        this->DeleteColumnByIndex(TargetColumnIndex);
    }

    virtual void __fastcall DeleteColumnByIndex(int TargetColumnIndex); // 列を削除する．

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

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

    virtual void __fastcall CopyCellFrom(TCFbEPrimitiveTable* SrcTable, int SrcRowIndex, int SrcColumnIndex, int DestRowIndex, int DestColumnIndex);  // SourceTable の RowIndex 行目，ColumnIndex 列目のセルをコピーする

    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 に入れて返す

    virtual void __fastcall UnableAllElements(void);

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

    THashedStringList*  FRowLabelList;
    THashedStringList*  FColumnLabelList;

    TObjectList*    RowList;

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

private:

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