/*
    TCFbECustomDataLoader.cpp    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.
*/
//---------------------------------------------------------------------------
#pragma hdrstop

#include "TCFbECustomDataLoader.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// コンストラクタ
__fastcall TCFbECustomDataLoader::TCFbECustomDataLoader(TCFbECustomCommandLineParser* Parser, bool IsVerbose, int TotalProcess, int BeginProcess)
{
    this->CurrentProcess = BeginProcess;
    this->TotalProcess = TotalProcess;

    // トレーニングデータの準備
    if (IsVerbose) {
        fprintf(stderr, "(%d/%d) Reading the following learning data.\n", this->CurrentProcess++, this->TotalProcess);
    }

    this->LearningData = new TCFbEDataSetEx();

    for (int k = 0; k < Parser->LearningDataFileNameList->Count; k++) {
        TFileName    CurrentFileName = Parser->LearningDataFileNameList->Strings[k];

        if (IsVerbose) {
            fprintf(stderr, "  %s\n", CurrentFileName.c_str());
        }

        TStringList* LearningDataStringList = new TStringList();

        try {
            LearningDataStringList->LoadFromFile(CurrentFileName);
        } catch (EFOpenError &efoe) {
            delete this->LearningData;
            delete LearningDataStringList;

            this->ErrorCode = -7;
            this->ErrorParameter = CurrentFileName;
            return;
        }                                           

        TCFbEDataSetEx*    BufferDataSet;
        try {
            BufferDataSet = new TCFbEDataSetEx(LearningDataStringList);
        } __finally {
            delete LearningDataStringList;
        }
//        this->LearningData->FillColumns(BufferDataSet);
        for (int i = 0; i < BufferDataSet->GetNumberOfRows(); i++) {
            this->LearningData->CopyRowFrom(BufferDataSet, i, true);
        }
        delete BufferDataSet;
    }

    // トレーニングデータ中の予測対象のメトリクスの状況を調べる
    if (Parser->TargetColumnLabelList->Text.Trim() != "*") {
        for (int j = 0; j < Parser->TargetColumnLabelList->Count; j++) {
            TTargetColumnType TargetColumnType = this->TargetColumnCheck(Parser, j);

            try {
                if (TargetColumnType == tmtEmpty) {    // 予測の元になるデータが存在しない
                    this->ErrorCode = -10;
                    this->ErrorParameter = Parser->TargetColumnLabelList->Strings[j];
                    return;

                } else if (TargetColumnType == tmtTooSparsity) {    // 予測の元になるデータが少なすぎる
                    this->ErrorCode = -11;
                    this->ErrorParameter = Parser->TargetColumnLabelList->Strings[j];
                    return;
                }

            } catch (...) {
                delete this->LearningData;
                throw;
            }
        }
    }

    if (IsVerbose) {
        fprintf(stderr, "    ..... completed: %d column(s) and %d row(s).\n\n", LearningData->GetNumberOfColumns(), LearningData->GetNumberOfRows());
    }
}

//---------------------------------------------------------------------------
__fastcall TCFbECustomDataLoader::~TCFbECustomDataLoader()
{
    delete this->LearningData;
}

//---------------------------------------------------------------------------
// 以下，protected メソッドの定義
//---------------------------------------------------------------------------
// 予測対象メトリクスがどのようなデータであるかを返す
TTargetColumnType __fastcall TCFbECustomDataLoader::TargetColumnCheck(TCFbECustomCommandLineParser* Parser, int TargetIndex)
{
    if (this->LearningData->GetNumberOfRows() == 0) {
        return tmtEmpty;
    }

    int    Index = (Parser->AlgorithmBase == abRow) ? this->LearningData->GetColumnLabelList()->IndexOf(Parser->TargetColumnLabelList->Strings[TargetIndex]) : this->LearningData->GetRowLabelList()->IndexOf(Parser->TargetColumnLabelList->Strings[TargetIndex]);
    if (Index == -1) {
        return tmtEmpty;
    }

    int    NumberOfEnableData = 0;

    if (Parser->AlgorithmBase == abRow) {
        for (int i = 0; i < this->LearningData->GetNumberOfRows(); i++) {
            if (this->LearningData->GetEnabledByIndex(i, Index)) {
                NumberOfEnableData++;
            }
        }
    } else {
        for (int j = 0; j < this->LearningData->GetNumberOfColumns(); j++) {
            if (this->LearningData->GetEnabledByIndex(Index, j)) {
                NumberOfEnableData++;
            }
        }
    }

    if (NumberOfEnableData == 0) {
        return tmtEmpty;
    }

    if (NumberOfEnableData < 2) {
        return tmtTooSparsity;
    }

    return tmtPredictable;
}

//---------------------------------------------------------------------------

