/***************************************************************************
 *   Copyright (C) 2005-2006 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 NUMBER_H
#define NUMBER_H

#include <ctype.h>

#include "common/global/global.h"
#include "key_enum.h"

//----------------------------------------------------------------------------
struct NumberBaseData {
  uint base;
  const char *prefix, *label,* key;
};

BEGIN_DECLARE_ENUM(NumberBase)
  Dec = 0, Hex, Bin, Oct, String
END_DECLARE_ENUM(NumberBase, NumberBaseData)

extern uint nbChars(NumberBase base, ulong value);
extern ulong maxValue(NumberBase base, uint nbChars);
inline uint convertNbChars(uint nb, NumberBase from, NumberBase to) { return nbChars(to, maxValue(from, nb)); }

extern char toChar(NumberBase base, uint value);
extern TQString toString(NumberBase base, ulong value, uint nbChars);
extern TQString toLabel(NumberBase base, ulong value, uint nbChars);
extern TQString toLabels(NumberBase base, const TQMemArray<ulong> &values, uint nbChars);

extern uint fromChar(NumberBase base, char c, bool *ok);
extern ulong fromString(NumberBase base, const char *s, uint size, bool *ok);
extern ulong fromString(NumberBase base, const TQString &s, bool *ok);
extern ulong fromLabel(NumberBase base, const TQString &s, bool *ok);
extern ulong fromLabel(NumberBase base, const TQString &s, uint nbChars, bool *ok);
extern ulong fromLabel(NumberBase base, const char *s, uint size, bool *ok);

extern ulong fromAnyLabel(const TQString &s, bool *ok);

//----------------------------------------------------------------------------
inline TQString toHex(ulong value, uint nbChars) { return toString(NumberBase::Hex, value, nbChars); }
inline TQString toHexLabel(ulong value, uint nbChars) { return toLabel(NumberBase::Hex, value, nbChars); }
inline TQString toHexLabelAbs(ulong value) { return toLabel(NumberBase::Hex, value, nbChars(NumberBase::Hex, value)); }

inline uint fromHex(char c, bool *ok) { return fromChar(NumberBase::Hex, c, ok); }
inline uint fromHex(TQChar c, bool *ok) { return fromChar(NumberBase::Hex, c.latin1(), ok); }
inline ulong fromHex(const char *s, uint size, bool *ok) { return fromString(NumberBase::Hex, s, size, ok); }
inline ulong fromHex(const TQString &s, bool *ok) { return fromString(NumberBase::Hex, s, ok); }
inline ulong fromHexLabel(const TQString &s, bool *ok) { return fromLabel(NumberBase::Hex, s, ok); }
inline ulong fromHexLabel(const TQString &s, uint nbChars, bool *ok)  { return fromLabel(NumberBase::Hex, s, nbChars, ok); }
inline ulong fromHexLabel(const char *s, uint size, bool *ok)  { return fromLabel(NumberBase::Hex, s, size, ok); }

//----------------------------------------------------------------------------
inline uint nbBits(ulong value) { return nbChars(NumberBase::Bin, value); }
inline uint nbBitsToNbChars(uint nbBits) { return nbBits/4 + (nbBits%4 ? 1 : 0); }
inline uint nbBitsToNbBytes(uint nbBits) { return nbBits/8 + (nbBits%8 ? 1 : 0); }
inline uint nbChars(ulong value) { return nbBitsToNbChars(nbBits(value)); }
inline uint nbBytes(ulong value) { return nbBitsToNbBytes(nbBits(value)); }

//----------------------------------------------------------------------------
extern TQString formatNumber(ulong v);
extern TQByteArray toAscii(const TQString &s);

//----------------------------------------------------------------------------
enum PrintMode { PrintAlphaNum, PrintEscapeAll };
inline TQString toPrintable(char c, PrintMode mode)
{
  if ( mode==PrintAlphaNum && isalnum(c) ) return TQChar(c);
  return "\\" + toHex(uchar(c), 2);
}
inline TQString toPrintable(const char *data, uint size, PrintMode mode)
{
  TQString s;
  for (uint i=0; i<size; i++) s += toPrintable(data[i], mode);
  return s;
}
inline TQString toPrintable(const TQString &s, PrintMode mode)
{
  TQByteArray a = toAscii(s);
  return toPrintable(a.data(), a.count(), mode);
}
inline TQString toPrintable(const TQMemArray<uchar> &data, PrintMode mode)
{
  return toPrintable((const char *)data.data(), data.size(), mode);
}

#endif
