/*
    TCFbECachedTable.h    November 27, 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 TCFbECachedTableH
#define TCFbECachedTableH
//---------------------------------------------------------------------------
#include <IniFiles.hpp>
#include <SysUtils.hpp>

// #include "Maprof.h"

#include "TCFbECell.h"
#include "TCFbEToolkit.h"
#include "TCFbEPrimitiveTable.h"
//---------------------------------------------------------------------------
class TCFbECachedTable : public TCFbEPrimitiveTable
{
public:
    // アクセサメソッド
    virtual void __fastcall SetValueByIndex(int TargetRowIndex, int TargetColumnIndex, double Value) {
        this->GetCellByIndex(TargetRowIndex, TargetColumnIndex)->SetValue(Value);
        this->CellIsUpdatedByIndex(TargetRowIndex, TargetColumnIndex);
    }

    virtual void __fastcall UnableElementByIndex(int TargetRowIndex, int TargetColumnIndex) {
        TCFbECell* Cell = this->GetCellByIndex(TargetRowIndex, TargetColumnIndex);
        if (Cell->GetEnabled()) {
            Cell->SetEnabled(false);
            this->CellIsUpdatedByIndex(TargetRowIndex, TargetColumnIndex);
        }
    }

    virtual TObjectList* GetChildCacheList(void) { return this->ChildCacheList; }

    virtual TCFbECachedTable* __fastcall GetChildCache(const char* ChildCacheName) { // ChildCacheName という名前のキャッシュを取得する
        int Index = this->ChildCacheLabelList->IndexOf(ChildCacheName);
        if (Index == -1) {
            return NULL;
        }
        return (TCFbECachedTable*)this->ChildCacheList->Items[Index];
    }

    virtual bool IsLinkedToParent(void) { return this->FIsLinkedToParent; }

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

    virtual void __fastcall InitCache(void);

    virtual void __fastcall DeleteRowByIndex(int TargetRowIndex);
    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 CopyAllElementsAndCache(TCFbECachedTable* SourceTable, bool AddLackCache, bool DeleteExcessiveCache);
    virtual void __fastcall RotatedCopyAllElementsAndCache(TCFbECachedTable* SourceTable, bool AddLackCache, bool DeleteExcessiveCache);

    virtual void __fastcall AddChildCache(TCFbECachedTable* ChildCache, const char* ChildCacheName, bool IsLinkedToParent); // ChildCache を ChildCacheName という名前のキャッシュとして追加する
    virtual void __fastcall DeleteChildCache(const char* ChildCacheName);            // ChildCacheName という名前のキャッシュを削除する

    virtual void __fastcall ParentCellIsUpdated(int RowIndex, int ColumnIndex); // 親キャッシュのセルが更新された
    virtual int __fastcall  ParentAddRow(const char* RowLabel) = 0;          // 親キャッシュの行が追加された
    virtual int __fastcall  ParentAddColumn(const char* ColumnLabel) = 0;    // 親キャッシュの列が追加された
    virtual void __fastcall ParentDeleteRowByIndex(int TargetRowIndex) = 0; // 親キャッシュの行が削除された
    virtual void __fastcall ParentDeleteColumnByIndex(int TargetColumnIndex) = 0;   // 親キャッシュの列が削除された
    
protected:
    virtual const AnsiString __fastcall GetRotatedChildCacheName(const char* ChildCacheName);  // ChildCacheName という名前のキャッシュの行と列を入れ替えたキャッシュの名前を取得する

    virtual TCFbECachedTable* GetChildCacheElement(int Index) {
        return (TCFbECachedTable*)this->ChildCacheList->Items[Index];
    }

    virtual void __fastcall SetCell(const char* RowLabel, const char* ColumnLabel, TCFbECell* Cell) {
        int RowIndex = this->GetRowLabelList()->IndexOf(RowLabel);
        int ColumnIndex = this->GetColumnLabelList()->IndexOf(ColumnLabel);
        this->SetCellByIndex(RowIndex, ColumnIndex, Cell);
    }

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

    virtual void __fastcall CellIsUpdated(const char* RowLabel, const char* ColumnLabel) {
        int RowIndex = this->FRowLabelList->IndexOf(RowLabel);
        int ColumnIndex = this->FColumnLabelList->IndexOf(ColumnLabel);
        this->CellIsUpdatedByIndex(RowIndex, ColumnIndex);
    }
    virtual void __fastcall CellIsUpdatedByIndex(int RowIndex, int ColumnIndex);

    virtual TCFbECachedTable* __fastcall CreateClone(void) = 0;             // 自分自身のクローンを作成する
    virtual TCFbECachedTable* __fastcall CreateRotatedClone(void) = 0;      // 自分自身の行と列が入れ替わったクローンを作成する

    TObjectList*        ChildCacheList;         // 子キャッシュのリスト
    THashedStringList*  ChildCacheLabelList;    // 子キャッシュの名前リスト
    bool                FIsLinkedToParent;      // 親キャッシュとリンクしているか否か

private:

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