/***************************************************************************
 *   Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org>             *
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/
#ifndef PIC_CONFIG_H
#define PIC_CONFIG_H

#include <tqmap.h>
#include <tqstringlist.h>

#include "common/common/bitvalue.h"
#include "pic_protection.h"
#include "pic.h"

namespace Pic
{
class Data;

BEGIN_DECLARE_ENUM(ConfigNameType)
  Default = 0, Extra, SDCC
END_DECLARE_ENUM_STD(ConfigNameType)

class Config
{
public:
  class Value {
  public:
    TQString name;
    TQMap<ConfigNameType, TQStringList> configNames;
    BitValue value;
    bool operator <(const Value &cv) const { return value<cv.value; }
    bool isValid() const { return !name.isEmpty(); }
  };

  class Mask {
  public:
    TQString name;
    BitValue value;
    TQValueVector<Value> values; // ordered from lower to higher
    bool operator <(const Mask &cm) const { return value<cm.value; }
  };

  class Word {
  public:
    TQString name;
    TQStringList ignoredCNames;
    BitValue wmask, pmask, cmask; // write, protected, and checksum bits masks
    BitValue bvalue;              // blank value
    TQValueVector<Mask> masks; // ordered from lower to higher
    BitValue usedMask() const;
  };

public:
  Config(const Pic::Data &data) : _data(data), _protection(data, *this) {}
  TQValueVector<Word> _words;
  const Protection &protection() const { return _protection; }

  const Value *findValue(const TQString &mask, const TQString &value) const;
  const Mask *findMask(const TQString &mask, uint *wordIndex = 0) const;
  static bool hasMaskName(const TQString &mask);
  static TQString maskLabel(const TQString &mask);
  bool checkValueName(const TQString &mask, const TQString &name) const;
  static TQString valueLabel(const TQString &mask, const TQString &name);

private:
  class MapData {
  public:
    MapData() {}
    MapData(int i, int b) : index(i), block(b) {}
    int index, block;
  };
  static TQMap<TQString, MapData> &masks();
  static TQMap<TQString, MapData> *_masks; // mask name -> index in DATA

  struct NameData {
    const char *name, *label;
  };
  enum Type { Fixed, ValueDouble, ValueUInt, Ratio, MemoryRange, Toggle, Pin, Pins };
  class Data {
  public:
    const NameData mask;
    Type type;
    const NameData values[50];
  };
  static const Data DATA[];

private:
  const Pic::Data &_data;
  Protection _protection;
};

TQDataStream &operator <<(TQDataStream &s, const Config::Value &value);
TQDataStream &operator >>(TQDataStream &s, Config::Value &value);
TQDataStream &operator <<(TQDataStream &s, const Config::Mask &mask);
TQDataStream &operator >>(TQDataStream &s, Config::Mask &mask);
TQDataStream &operator <<(TQDataStream &s, const Config::Word &word);
TQDataStream &operator >>(TQDataStream &s, Config::Word &word);
TQDataStream &operator <<(TQDataStream &s, const Config &config);
TQDataStream &operator >>(TQDataStream &s, Config &config);

} //namespace

#endif
