/*
    TCFbEDocfbeCommandLineParser.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 "TCFbEDocfbeCommandLineParser.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
// コンストラクタ（argc と argv によってコマンドラインを与える
__fastcall TCFbEDocfbeCommandLineParser::TCFbEDocfbeCommandLineParser(int argc, char* argv[])
    : TCFbECustomCommandLineParser(argc, argv)
{
    this->EstimatingDataFileNameList = new TStringList();    

    if (this->HelpEnabled || (this->ErrorCode != 0)) {
        return;
    }

    try {
        // -e, --estimating パラメータの検査
        this->EstimatingDataFileNameList->DelimitedText = this->GetValueString("-e", "--estimating");
        if (this->EstimatingDataFileNameList->Count <= 0) {
            this->ErrorCode = 3;
            return;
        }
        for (int k = 0; k < this->EstimatingDataFileNameList->Count; k++) {
            if (!FileExists(this->EstimatingDataFileNameList->Strings[k])) {
                this->ErrorCode = -1;
                this->ErrorParameter = this->EstimatingDataFileNameList->Strings[k];
                return;
            }
        }

        // -p, --prediction パラメータの検査
        this->PredictionName = this->GetValueString("-p", "--prediction");
        if (this->PredictionName.IsEmpty()) {
            this->ErrorCode = 5;
            return;
        } else {
            TCFbEPredictionAlgorithm* PA = CreatePredictionAlgorithm(this->PredictionName);
            if (PA == NULL) {
                this->ErrorCode = -3;
                this->ErrorParameter = this->PredictionName;
                return;
            }
            delete PA;
        }

        // -ns,--neighbors-size パラメータの検査
        AnsiString NSString = this->GetValueString("-ns", "--neighbors-size");
        if (NSString.IsEmpty()) {
            this->NeighborsSize = 0;
        } else {
            try {
                this->NeighborsSize = NSString.ToInt();
            } catch (EConvertError &ece) {
                this->ErrorCode = -5;
                this->ErrorParameter = NSString;
                return;
            }
        }

        // -ca,--case-amplifier パラメータの検査
        AnsiString CAString = this->GetValueString("-ca", "--case-amplifier");
        if (CAString.IsEmpty()) {
            this->CaseAmplifier = 1.0;
        } else {
            try {
                this->CaseAmplifier = CAString.ToDouble();
            } catch (EConvertError &ece) {
                this->ErrorCode = -16;
                this->ErrorParameter = CAString;
                return;
            }
        }

        // -vp, --vw-prediction パラメータの検査
        this->VWPredictionName = this->GetValueString("-vp", "--vw-prediction");
        if (this->VWPredictionName.IsEmpty()) {
            if (this->PredictionName == "AmplifiedWeightedSumWithVWWeightedMultiplier") {
                this->ErrorCode = -21;
                this->ErrorParameter = "";
                return;
            }
        } else {
            TCFbESimilarityComputationAlgorithm* VWPA = this->CreateSimilarityComputationAlgorithm(this->VWPredictionName);
            if (VWPA == NULL) {
                this->ErrorCode = -18;
                this->ErrorParameter = this->VWPredictionName;
                return;
            }
            delete VWPA;

            if (this->PredictionName != "AmplifiedWeightedSumWithVWWeightedMultiplier") {
                this->ErrorCode = -19;
                this->ErrorParameter = this->PredictionName;
                return;
            }
        }

        // -m, --merge パラメータの検査
        AnsiString MergeBaseString = this->GetValueString("-m", "--merge");
        if (MergeBaseString.IsEmpty() || (MergeBaseString.AnsiCompareIC("both") == 0)) {
            this->MergeBase = tmbBoth;
        } else if (MergeBaseString.AnsiCompareIC("none") == 0) {
            this->MergeBase = tmbNone;
        } else if (MergeBaseString.AnsiCompareIC("learning") == 0) {
            this->MergeBase = tmbLearningData;
        } else if (MergeBaseString.AnsiCompareIC("estimating") == 0) {
            this->MergeBase = tmbEstimatingData;
        } else {
            this->ErrorCode = -15;
            this->ErrorParameter = MergeBaseString;
            return;
        }

        // -dn, --disp-neighbors パラメータの検査
        this->DisplayNeighbors = this->IsEnableOption("-dn", "--disp-neighbors");

        // -ds, --disp-similarities パラメータの検査
        this->DisplaySimilarities = this->IsEnableOption("-ds", "--disp-similarities");

        // -dv, --disp-values パラメータの検査
        this->DisplayValues = this->IsEnableOption("-dv", "--disp-values");

        // -dd, --disp-distribution パラメータの検査
        this->DisplayDistribution = this->IsEnableOption("-dd", "--disp-distribution");

        // -r, --recommendation パラメータの検査
        this->Recommendation = this->IsEnableOption("-r", "--recommendation");

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

//---------------------------------------------------------------------------
__fastcall TCFbEDocfbeCommandLineParser::~TCFbEDocfbeCommandLineParser()
{
    delete this->EstimatingDataFileNameList;
}

//---------------------------------------------------------------------------
// ヘルプ文字列を返す
AnsiString __fastcall TCFbEDocfbeCommandLineParser::GetHelpString(void)
{
    return
        //            0         1         2         3         4         5         6         7
        //            01234567890123456789012345678901234567890123456789012345678901234567890123456789
          AnsiString("USAGE:                                                                         \n")
        + AnsiString("  docfbe [OPTIONS] -l=FILENAMES -e=FILENAMES -s=ALGORITHM -p=ALGORITHM         \n")
        + AnsiString("\n")
        + AnsiString("where,                                                                         \n")
        + AnsiString("  -l, --learning=FILENAMES   Learning Data filenames separated by comma.       \n")
        + AnsiString("  -e, --estimating=FILENAMES Estimating Data filenames separated by comma.     \n")
        + AnsiString("  -s, --similarity=ALGORITHM Similarity computation algorithm.                 \n")
        + AnsiString("  -p, --prediction=ALGORITHM Prediction algorithm.                             \n")
        + AnsiString("\n")
        + AnsiString("OPTIONS are specified as:                                                      \n")
        + AnsiString("  -h, --help                 Display this help and exit.                       \n")
        + AnsiString("  -n, --normalize=METHOD     Method to normalize values. METHOD is specified as\n")
        + AnsiString("                             value | normalize | standardize | order           \n")
        + AnsiString("  -i, --itembased            Apply item-based collaborative filtering.         \n")
        + AnsiString("  -ns,--neighbors-size=SIZE  Neighbors size; i.e., how much similar rows will  \n")
        + AnsiString("                             be used for estimating.                           \n")
        + AnsiString("  -d, --default=VALUE        Default value is put instead of missing values.   \n")
        + AnsiString("  -if,--inverse-frequency    Inverse Case Frequency is applied.                \n")
        + AnsiString("  -ca,--case-amplifier=VALUE Case Amplification is applied.                    \n")
        + AnsiString("  -vs,--vw-similarity=ALGORITHM   Variable Weighting is applied for similarity \n")
        + AnsiString("                                  computation.                                 \n")
        + AnsiString("  -vp,--vw-prediction=ALGORITHM   Variable Weighting is applied for prediction.\n")
        + AnsiString("  -t, --target=LABEL[,LABEL] Target columns to estimate. Unspecified denotes   \n")
        + AnsiString("                             all unknown columns will be estimated. Or \"*\"   \n")
        + AnsiString("                             indicates all columns will be estimated.          \n")
        + AnsiString("  -m, --merge=BASEDATA       Base dataset in merging data.  BASEDATA is        \n")
        + AnsiString("                             specified as: none | both | learning | estimating \n")
        + AnsiString("  -dn,--disp-neighbors       Display neighbors with the results.               \n")
        + AnsiString("  -ds,--disp-similarities    Display neighbors' similarities with the results. \n")
        + AnsiString("  -dv,--disp-values          Display neighbors' values with the results.       \n")
        + AnsiString("  -dd,--disp-distribution    Display distribution of the similarities.         \n")
        + AnsiString("  -r, --recommendation       Output as recommendation form.                    \n")
        + AnsiString("  -o, --output=FILENAME      File name for outputting the results.             \n")
        + AnsiString("\n")
        + AnsiString("Similarity computation algorithm and variable weighting algorithm are specified\n")
        + AnsiString("as one of the following terms:                                                 \n")
        + AnsiString("  CosineSimilarity                                                             \n")
        + AnsiString("  AdjustedCosineSimilarityWithAverage                                          \n")
        + AnsiString("  AdjustedCosineSimilarityWithMedian                                           \n")
        + AnsiString("  CorrelationCoefficientWithAverage                                            \n")
        + AnsiString("  CorrelationCoefficientWithMedian                                             \n")
        + AnsiString("  RankCorrelation                                                              \n")
        + AnsiString("  DistanceSimilarityWithAverage                                                \n")
        + AnsiString("  DistanceSimilarityWithMedian                                                 \n")
        + AnsiString("\n")
        + AnsiString("Prediction algorithm is specified as one of the following terms:               \n")
        + AnsiString("  WeightedSum                                                                  \n")
        + AnsiString("  AdjustedWeightedSumWithAverageOfColumn                                       \n")
        + AnsiString("  AdjustedWeightedSumWithMedianOfColumn                                        \n")
        + AnsiString("  AdjustedWeightedSumWithAverageOfNeighbors                                    \n")
        + AnsiString("  AdjustedWeightedSumWithMedianOfNeighbors                                     \n")
        + AnsiString("  AdjustedWeightedSumWithAverageOfRow                                          \n")
        + AnsiString("  AdjustedWeightedSumWithMedianOfRow                                           \n")
        + AnsiString("  AmplifiedWeightedSumWithAveragedMultiplier                                   \n")
        + AnsiString("  AmplifiedWeightedSumWithMedianOfMultiplier                                   \n")
        + AnsiString("  AmplifiedWeightedSumWithVWWeightedMultiplier                                 \n")
        + AnsiString("\n")
        + AnsiString("EXAMPLES:                                                                      \n")
        + AnsiString("  docfbe -l=learning.csv -e=estimating.csv -s=CosineSimilarity -p=WeightedSum  \n")
        + AnsiString("\n")
        + AnsiString("  docfbe --learning=learning.csv --estimating=estimating.csv --similarity=Cosin\n")
        + AnsiString("  eSimilarity --prediction=WeightedSum                                         \n")
        + AnsiString("\n")
        + AnsiString("  docfbe -n=normalize -i -ns=10 -t=BUG,EFFORT -dn -ds -dd -o=output.txt -l=lear\n")
        + AnsiString("  ning.csv -e=estimating.csv -s=CosineSimilarity -p=WeightedSum                \n")
        + AnsiString("\n")
        + AnsiString("  docfbe --normalize=normalize --itembased --neighbors-size=10 --target=BUG,EFF\n")
        + AnsiString("  ORT --disp-neighbors --disp-similarities --disp-distribution --output=output.\n")
        + AnsiString("  txt --learning=learning.csv --estimating=estimating.csv --similarity=CosineSi\n")
        + AnsiString("  milarity --prediction=WeightedSum                                            \n");
}

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

