// Parameter class implementation.
//
// Copyright 2001, KUN
//
// 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

// $Id: paramtab.cc,v 1.7 2003/09/27 00:46:42 murphy Exp $

using namespace std;
#include <assert.h>
#include <stdio.h> // for snprintf()
#include <string>
//#include <stream.h>	// FN: for dec(), obsolete
#include "globsetafftable.h"
#include "paramtab.h"

//------------------------------------------------------------------------------
// Functions for type Param:
//------------------------------------------------------------------------------

Param*
merge(const Param& p1, const Param& p2)
{
    Param* res;

    switch (p1.type) {
        case TextType:
            res = new Param(p1.type, p1.value.id);
            break;
        case IntType:
            res = new Param(p1.value.number);
            break;
        case AnyInt:
        case AnyText:
            res = new Param(p1.type);
            break;
        case IdType:
            if (p2.type == SetType) {
                res = new Param(affix_table.merge(p1.value.id, p2.value.set));
            } else {
                res = new Param(affix_table.merge(p1.value.id, p2.value.id));
            }
            break;
        case SetType:
            if (p2.type == SetType) {
                res = new Param(affix_table.merge(p1.value.set, p2.value.set));
            } else {
                res = new Param(affix_table.merge(p1.value.set, p2.value.id));
            }
            break;
        default:
            assert(!"unknown param type");
            res = 0; // to keep gcc happy
    }

    return res;
}

string Param::to_string() const
{
    switch (type) {
        case IdType:
            return idtable.to_string(value.id);
            break;
        case SetType:
            return convert_to_string(value.set);
        case TextType:
            return idtable.to_string(value.id);
            break;
        case IntType:
            //return string(dec(value.number));
	    char cbuf[99];
	    snprintf(cbuf, sizeof(cbuf), "%ld", value.number);
	    return string(cbuf);
            break;
        case AnyText:
            return "TEXT";
            break;
        case AnyInt:
            return "INT";
            break;
        default:
            return "<ERROR>";
  }
}

//------------------------------------------------------------------------------
// Functions for type ParamTable:
//------------------------------------------------------------------------------

pParam
ParamTable::merge(const pParam& p1, const pParam& p2)
{
    if (!p1) return 0;
    pParam next = merge(p1->next, p2->next);
    Param* p = ::merge(p1->elem, p2->elem);
    pParam res = enter(*p, next);
    delete p;
    return res;
}
