/*
 *  A utility for building various tables and specializations for the
 *  KJS Frostbyte bytecode
 *
 *  Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org)
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 *
 */

#include <iostream>
#include <fstream>
#include <string>

using std::ifstream;
using std::ofstream;
using std::string;

#ifndef FILE_TEMPLATE_H
#define FILE_TEMPLATE_H

static inline bool stringEndsWith(string base, string suffix)
{
    if (base.length() < suffix.length()) {
        return false;
    }
    return base.substr(base.length() - suffix.length()) == suffix;
}

struct FileTemplate {
    FileTemplate(string inFileName, string outFileName):
        inFileName(inFileName), outFileName(outFileName)
    {
        isOK  = true;
        lines = 0;

        in.open(inFileName.c_str());
        if (in.fail()) {
            std::cerr << "Unable to open:" << inFileName << "\n";
            isOK = false;
        }

        out.open(outFileName.c_str());
        if (out.fail()) {
            std::cerr << "Unable to open:" << outFileName << "\n";
            isOK = false;
        }

        if (isOK) {
            out << "// WARNING: Portions of this file are autogenerated from codes.def and " << inFileName << ".\n";
            out << "// (which is what the licensing terms apply to)\n";
            out << "// Any changes you make here may be lost!\n";
            handleUntilGenerate();
        }
    }

    ~FileTemplate()
    {
        if (isOK) {
            handleUntilGenerate();
        }
    }

    // Goes until @generate..
    void handleUntilGenerate()
    {
        out << "#line " << (lines + 1) << " \"" << inFileName << "\"\n";
        while (!in.eof()) {
            string line;
            getline(in, line);
            ++lines;
            if (stringEndsWith(line, "@generate")) {
                break;
            } else {
                out << line << "\n";
            }
        }
    }

    void handleSuffix()
    {
        out << "#line " << (lines + 1) << " \"" << inFileName << "\"\n";
        while (!in.eof()) {
            string line;
            getline(in, line);
            out << line << "\n";
        }
    }

    string   inFileName;
    string   outFileName;
    ifstream in;
    ofstream out;
    bool         isOK;
    bool ok()
    {
        return isOK;
    }
    int lines; // from the template

};

#endif

