/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#ifndef MVMISCELANEOUS_H_
#define MVMISCELANEOUS_H_

#include <algorithm>
#include <string>
#include <sstream>
#include <set>
#include <vector>

#ifdef METVIEW
#include "MvRequest.h"
#endif

namespace metview
{
std::string iconDirFile(const std::string& fName);
std::string etcDirFile(const std::string& fName);
std::string appDefDirFile(const std::string& fName);
std::string preferenceDirFile(const std::string& fName);
std::string magicsStylesEcmwfDirFile(const std::string& fName);
std::string magicsStylesDirFile(const std::string& fName);
std::string stylePreviewDirFile(const std::string& fName);
std::string ecchartsDirFile(const std::string& fName);
std::string mvlMacroDirFile(const std::string& fName);
std::string webBrowser();
bool openInBrowser(const std::string& url, std::string& errStr);

void shellCommand(const std::string&, std::stringstream&, std::stringstream&);
bool createWorkDir(const std::string& prefix, std::string& tmpPath, std::string& errTxt);

bool checkGrid(const std::vector<std::string>& areaStr, const std::vector<std::string>& gridStr,
               std::vector<std::string>& numXy, std::string& errStr);

std::string simplified(const std::string& str);
inline bool isSpace(unsigned char c) {
    return (c == ' ' || c == '\t' || c == '\n');
}
inline void removeSpaces(std::string& s) {
    s.erase(remove_if(s.begin(), s.end(), metview::isSpace), s.end());
}

//! Returns a string value for writing ; use a missing identifier if empty
//! Used for geopoints stnids
std::string stationIdForWritingToFile(const std::string &in);
std::string stationIdFromFile(const std::string &in);

bool isNumber(const std::string& v);
std::string toBold(int v);
std::string toBold(float v);
std::string toBold(const std::string&);
std::string beautify(const std::string& name);
inline void toLower(std::string& v) {std::transform(v.begin(), v.end(), v.begin(), ::tolower);}
inline void toUpper(std::string& v) {std::transform(v.begin(), v.end(), v.begin(), ::toupper);}
std::string replace(const std::string& data, const std::string& oldStr, const std::string& newStr);

bool isForceMarsLogSet();
inline bool isPidValid(int pid) {return (pid > 2 && pid < 100000);}

double truncate(double, int);

#ifdef METVIEW
void writeFileToLogWarn(const std::string& fileName, int maxLineNum = -1);
void writeFileToLogInfo(const std::string& fileName, int maxLineNum = -1);
void writeFileToLogErr(const std::string& fileName, int maxLineNum = -1);
void writeFileToLog(int, const std::string& fileName, int maxLineNum = -1);
#endif

std::string getLastLines(const std::string& fileName, int lastLineNum, std::string& error_msg);

#ifdef METVIEW
std::string pathFromFieldsetWrittenToDisk (const MvRequest &req);
#endif


inline std::string merge(const std::vector<std::string>& v, const std::string& sep)
{
    std::string res;
    for (size_t i = 0; i < v.size(); i++) {
        if (i > 0)
            res += sep;
        res += v[i];
    }
    return res;
}

inline std::string toMacroList(const std::vector<std::string>& v)
{
    std::string res;
    for (size_t i = 0; i < v.size(); i++) {
        if (i > 0)
            res += ",";
        res += v[i];
    }

    if (v.size() >= 1)
        res = "[" + res + "]";

    return res;
}

inline std::string stepToMacro(const std::vector<std::string>& v)
{
    std::string res;

    bool useQuote = false;
    for (size_t i = 0; i < v.size(); i++) {
        std::string s = v[i];
        toLower(s);
        if (s.find("-") != std::string::npos || s == "to" || s == "by") {
                useQuote = true;
                break;
        }
    }

    for (size_t i = 0; i < v.size(); i++) {
        if (i > 0)
            res += ",";

        if (useQuote) {
            res += "\'" + v[i] + "\'";
        } else {
            res += v[i];
        }
    }

    if (v.size() >= 1)
        res = "[" + res + "]";

    return res;
}


template <typename TYPE>
inline std::string toString(const TYPE& in)
{
    std::ostringstream os;
    os << in;
    return os.str();
}

template <typename TYPE>
inline TYPE fromString(const std::string& in)
{
    std::istringstream iss(in);
    TYPE v;
    iss >> v;
    return v;
}

}  // namespace metview

#endif
