#include "part.h"


extern "C" {
#if defined(__WINDOWS__)
#include "avrdude/libavrdude.h"
#else
#include "libavrdude.h"
#endif

/*
#include "avrdude/avrdude.h"
#include "avrdude/avr.h"
#include "avrdude/config.h"
#include "avrdude/confwin.h"
#include "avrdude/fileio.h"
#include "avrdude/lists.h"
#include "avrdude/par.h"
#include "avrdude/pindefs.h"
#include "avrdude/term.h"
#include "avrdude/safemode.h"
#include "avrdude/update.h"
#include "avrdude/usbasp.h"
#include "avrdude/avrpart.h"
*/
}

class PartPrivate {
  public:
    struct avrpart * part;
};

Part * Part::locatePart(const std::string & name) {
  struct avrpart * part = locate_part(::part_list, (char*)name.c_str());
  if (part) {
    Part * p = new Part();
    p->priv->part = part;
    ::avr_initmem(part);
    return p;
  }
  return 0;
}


Part::Part() {
  priv = new  PartPrivate();
}

Part::~Part() {
  delete priv;
}

Part * Part::clone() {
  struct avrpart * part = avr_dup_part(priv->part);
  if (part) {
    Part * p = new Part();
    p->priv->part = part;
    return p;
  }
  return 0;
}

void * Part::getPointer() {
  return priv->part;
}

static char tohexchar(int value) {
  return (value<10)?(value+'0'):(value+'a'-10);
}

static std::string bytetohex(int value) {
  std::string retval;
  retval += tohexchar((value&0xf0)>>4);
  retval += tohexchar((value&0x0f)>>0);
  return retval;
}


std::string Part::get_signature() {
  std::string retval;
  retval += bytetohex(priv->part->signature[0]);
  retval += bytetohex(priv->part->signature[1]);
  retval += bytetohex(priv->part->signature[2]);
  return retval;
}


static std::vector<PartInfo> localPartInfo;

static void walkPartCB(const char *name, const char *desc, const char *cfgname, int cfglineno, void *cookie) {
  localPartInfo.push_back(PartInfo());
  localPartInfo.back().name = name;
  localPartInfo.back().desc = desc;
  localPartInfo.back().cfgname = cfgname;
  localPartInfo.back().cfglineno = cfglineno;
}

std::vector<PartInfo> Part::getAvailableParts() {
  ::walk_avrparts(::part_list, &walkPartCB , 0);
  return localPartInfo;
}


