
/*LICENSE_START*/
/*
 *  Copyright (C) 2014  Washington University School of Medicine
 *
 *  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 of the License, or
 *  (at your option) 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 this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
/*LICENSE_END*/

#include <QtGlobal>

#define __APPLICATION_INFORMATION_DECLARE__
#include "ApplicationInformation.h"
#undef __APPLICATION_INFORMATION_DECLARE__

#include "CaretOMP.h"
#include "FileInformation.h"

using namespace caret;


    
/**
 * \class caret::ApplicationInformation 
 * \brief Provides application information.
 *
 * Provides application information (name, version, etc).
 */

/**
 * Constructor.
 */
ApplicationInformation::ApplicationInformation()
: CaretObject()
{ 
    this->workbenchSpecialVersion = WorkbenchSpecialVersionEnum::WORKBENCH_SPECIAL_VERSION_NO;
    //this->workbenchSpecialVersion = WorkbenchSpecialVersionEnum::WORKBENCH_SPECIAL_VERSION_FIRST_CHARTING;

    this->name = "Connectome Workbench";
    this->nameForGuiLabel = this->name;
    switch (this->workbenchSpecialVersion) {
        case WorkbenchSpecialVersionEnum::WORKBENCH_SPECIAL_VERSION_NO:
            /* use default naming */
            break;
        case WorkbenchSpecialVersionEnum::WORKBENCH_SPECIAL_VERSION_FIRST_CHARTING:
            this->name = "Connectome Workbench (First Charting Version)";
            this->nameForGuiLabel = ("<html>"
                                     "Connectome Workbench<br>"
                                     "(First Charting Version)"
                                     "</html>");
            break;
    }
    /*
     * Version now gets set at the top of the main CMakeLists.txt only.
     */
    this->version = "@VERSION@";
    this->commit = "Commit: @COMMIT@";
    this->commitDate = "Commit Date: @COMMIT_DATE@";

#ifdef NDEBUG
    this->compiledWithDebugOn = "Compiled Debug: NO";
#else
    this->compiledWithDebugOn = "Compiled Debug: YES";
#endif // NDEBUG

#ifdef CARET_OMP
    this->compiledWithOpenMP = "Compiled with OpenMP: YES";
#else
    this->compiledWithOpenMP = "Compiled with OpenMP: NO";
#endif

    this->operatingSystemName = "Operating System: Unknown";
    
#ifdef CARET_OS_LINUX
    this->operatingSystemName = "Operating System: Linux";
#endif // CARET_OS_MACOSX
    
#ifdef CARET_OS_MACOSX
    this->operatingSystemName = "Operating System: Apple OSX";
#endif // CARET_OS_MACOSX
    
#ifdef CARET_OS_WINDOWS
    this->operatingSystemName = "Operating System: Windows";
#endif // CARET_OS_MACOSX
}

/**
 * Destructor.
 */
ApplicationInformation::~ApplicationInformation()
{
    
}

/**
 * @return Name of the application.
 */
AString 
ApplicationInformation::getName() const
{
    return this->name;
}

/**
 * @return Name of the application formatted
 *         specifically for use in a GUI QLabel.
 */
AString 
ApplicationInformation::getNameForGuiLabel() const
{
    return this->nameForGuiLabel;
}

/**
 * @return Version of application.
 */
AString 
ApplicationInformation::getVersion() const
{
    return this->version;
}

/**
 * @return Commit info of application.
 */
AString 
ApplicationInformation::getCommit() const
{
    return this->commit;
}

/**
 * @return Commit date of application.
 */
AString 
ApplicationInformation::getCommitDate() const
{
    return this->commitDate;
}

/**
 * @return Text indicating if Workbench was compiled with Debug on.
 */
AString
ApplicationInformation::getCompiledWithDebugStatus() const
{
   return this->compiledWithDebugOn;
}
        

/**
 * Get all information.
 * @param informationValues
 *    Output information.
 */
void 
ApplicationInformation::getAllInformation(std::vector<AString>& informationValues) const
{
    informationValues.clear();
    
    informationValues.push_back(this->name);
    
    informationValues.push_back("Type: " + ApplicationTypeEnum::toGuiName(s_applicationType));

    informationValues.push_back("Version: " + this->version);
    
    informationValues.push_back("Qt Compiled Version: " + QString(QT_VERSION_STR));
    
    informationValues.push_back("Qt Runtime Version: " + QString(qVersion()));
    
    informationValues.push_back(commit);
    
    informationValues.push_back(commitDate);

#if defined COMPILER_NAME
    FileInformation fileInfo(COMPILER_NAME);
    informationValues.push_back(QString("Compiler: ") + fileInfo.getFileNameFollowedByPathNameForGUI());
#endif 
#if defined COMPILER_VERSION
    informationValues.push_back(QString("Compiler Version: ") + QString(COMPILER_VERSION));
#endif 

    informationValues.push_back(this->compiledWithDebugOn);

    informationValues.push_back(this->operatingSystemName);

    informationValues.push_back(compiledWithOpenMP);
}

/**
 * Get all of the application information in a string with each line
 * separated by the given 'separator'.
 *
 * @param separator
 *    The separator is placed between each line of information.  A newline
 *    ("\n") is commonly used for the separator.
 */
AString
ApplicationInformation::getAllInformationInString(const AString& separator) const
{
    std::vector<AString> informationValues;
    getAllInformation(informationValues);
    
    AString infoOut;
    for (std::vector<AString>::iterator iter = informationValues.begin();
         iter != informationValues.end();
         iter++) {
        infoOut += *iter;
        infoOut += separator;
    }
    
    return infoOut;
}

AString
ApplicationInformation::getSummaryInformationInString(const AString& separator) const
{
    AString infoOut = "Version: " + version + separator;
    infoOut += commitDate + separator;
    infoOut += operatingSystemName + separator;
    return infoOut;
}

/**
 * @return The Workbench Special Version
 *
 * Used for versions of Workbench that may or may 
 * not be released and contains special functionality.
 */
WorkbenchSpecialVersionEnum::Enum 
ApplicationInformation::getWorkbenchSpecialVersion() const
{
    return this->workbenchSpecialVersion;
}

/**
 * @return The type of application.
 */
ApplicationTypeEnum::Enum 
ApplicationInformation::getApplicationType()
{
    return s_applicationType;
}
        
/**
 * Set the application type.
 *
 * @param applicationType
 *    New value for application type.
 */
void 
ApplicationInformation::setApplicationType(const ApplicationTypeEnum::Enum applicationType)
{
    s_applicationType = applicationType;
}
        


