/*
 *                            COPYRIGHT
 *
 *  pcb2ncap, simple PCB file to ncap file program converter
 *  Copyright (C) 2001 Luis Claudio Gambôa Lopes
 *
 *  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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Contact address for Email:
 *  lcgamboa@yahoo.com
 *
 */


#include<stdio.h>
#include<sys/stat.h>

#include<iostream>
#include<fstream>
#include<string>
using namespace std;


class signal
{
public:
  string des, xpos, ypos;
};


class module
{
private:
public:
  int number;
  int type;
  int npins;
  int variant;
  string description;
  int position;
  string xposition;
  string yposition;
  string orientation;

  string des;
  string ref;

  signal signals[100];

    module (string);
  void print (void);
  void make (void);
};


int pin = 1, pos = 0, ndevices = 0;
ifstream arq;
ofstream arq2;
module *devices[500];
int layers = 2, xstart = 0, ystart = 0;
string xsize, ysize;

void
module::print (void)
{
  arq2 << number << endl << type << endl << npins << endl << variant << endl
    << description << endl << position << endl << xposition << endl <<
    yposition << endl << orientation << endl;
  for (int i = 1; i <= npins; i++)
    arq2 << signals[i].des << endl;
};

void
module::make (void)
{
  char fname[100];
  char fname2[100];
  mkdir ("outlines", S_IRWXU | S_IRWXG);
  sprintf (fname, "outlines/dev%i.%i.0", type, npins);
  ofstream out (fname);
  out << "paddef:\ntracking circle 60\npower annulus 80\nend\npins\n";

  int x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7;
  int xpos, ypos;
  for (int i = 0; i < npins; i++)
    {
      xpos = atoi (signals[i].xpos.c_str ()) - atoi (xposition.c_str ());
      ypos = atoi (signals[i].ypos.c_str ()) - atoi (yposition.c_str ());
  //    ypos = atoi (yposition.c_str ()) - atoi (signals[i].ypos.c_str ());

      out << xpos << ',' << ypos << endl;

      if (xpos < x1)
	x1 = xpos;
      if (xpos > x2)
	x2 = xpos;
      if (ypos < y1)
	y1 = ypos;
      if (ypos > y2)
	y2 = ypos;
    };
  out << "end\n";
  x1 -= 30;
  x2 += 30;
  y1 -= 30;
  y2 += 30;

  out << x1 << ',' << y1 << ',' << x2 << ',' << y1 << endl;
  out << x2 << ',' << y1 << ',' << x2 << ',' << y2 << endl;
  out << x2 << ',' << y2 << ',' << x1 << ',' << y2 << endl;
  out << x1 << ',' << y2 << ',' << x1 << ',' << y1 << endl;

  out.close ();
  sprintf (fname2, "outlines/tab.%i", type);
  out.open (fname2);
  out << "description\n!\n" << npins << ".0";
};


void
strip (string s)
{
  while (s[pos] != '(')
    pos++;
};

string
parse_quotes (string s)
{
  string out = "";
  while (s[pos] != '\"')
    pos++;
  pos++;
  while (s[pos] != '\"')
    out += s[pos++];
  pos++;
  return out;
};

string
parse_space (string s)
{
  string out = "";
  while ((pos < s.size ()) && (s[pos] != '\t') && (s[pos] != ' ')
	 && (s[pos] != '('))
    pos++;
  pos++;
  while ((pos < s.size ()) && (s[pos] != '\t') && (s[pos] != ' ')
	 && (s[pos] != ')'))
    out += s[pos++];
  return out;
};

void
parse_element (string s)
{
  pos = s.find ("PCB");
  if (pos >= 0)
    {
      pos = 0;
      parse_quotes (s);		//description
      xsize = parse_space (s);
      ysize = parse_space (s);
    };

  pos = s.find ("Element(");
  if (pos >= 0)
    {
      devices[ndevices] = new module (s);
      pin = 0;
    };

  pos = s.find ("Pin");
  if (pos >= 0)
    {
      pos = 0;
      strip (s);
      devices[ndevices - 1]->signals[pin].xpos = parse_space (s);
      devices[ndevices - 1]->signals[pin].ypos = parse_space (s);
      pin++;
      devices[ndevices - 1]->npins = pin;
    }
  pos = s.find ("Pad");
  if (pos >= 0)
    {
      pos = 0;
      strip (s);
      devices[ndevices - 1]->signals[pin].xpos = parse_space (s);
      devices[ndevices - 1]->signals[pin].ypos = parse_space (s);
      pin++;
      devices[ndevices - 1]->npins = pin;
    }
/*  
  pos=s.find("ElementLine");	
  if(pos >= 0)
    cout<<"ElementLine: "<<s<<endl;
  
  pos=s.find("ElementArc");	
  if(pos >= 0)
    cout<<"ElementArc: "<<s<<endl;
*/
  pos = s.find ("Mark");
  if (pos >= 0)
    {
      pos = 0;
      strip (s);
      devices[ndevices - 1]->xposition = parse_space (s);
      devices[ndevices - 1]->yposition = parse_space (s);
    };
};

void
parse_signal (string s)
{
  int pos2 = 0;
  string signal = "", sig = "", uname, upin;
  pos = 0;
  while ((s[pos] != ' ') && (s[pos] != '\t'))
    {
      signal += s[pos];
      pos++;
    };
  while (s[pos] != '\0')
    {
      sig = "";
      sig = parse_space (s);
      if (sig.size () > 0)
	{
	  pos2 = 0;
	  uname = "";
	  while (sig[pos2] != '-')
	    {
	      uname += sig[pos2];
	      pos2++;
	    };
	  pos2++;
	  upin = "";
	  while (pos2 < sig.size ())
	    {
	      upin += sig[pos2];
	      pos2++;
	    };

	  for (int o = 0; o < ndevices; o++)
	    for (int p = 0; p < devices[o]->npins; p++)
	      if (devices[o]->description == uname)
		devices[o]->signals[atoi (upin.c_str ())].des = signal;
	};
    };

};


module::module (string s)
{
  pos = 0;

  des = parse_quotes (s);
  description = parse_quotes (s);
  ref = parse_quotes (s);
  orientation = "0";
  number = ndevices++;
  type = number;
  npins = 0;
  variant = 0;
  position = 1;
  for (int i = 0; i < 100; i++)
    signals[i].des = "NC";
};


void
main (int argc, char **argv)
{
  int elm, bytes = 0;
  string s;
  int pins = 0;

  if (argc < 2)
    {
      cout << "usage: " << argv[0] << " pcbfile <netfile>" << endl;
      exit (0);
    };

  string fname = argv[1];
  arq.open (fname.c_str ());
  fname.replace(fname.find(".pcb"),5,".ncap");
  arq2.open (fname.c_str ());

  while (getline (arq, s))
    {
      parse_element (s);
    };
  arq.close ();

  arq.open (argv[2]);

  while (getline (arq, s))
    {
      parse_signal (s);
    };


  arq2 << "ncapture" << endl << 0 << endl << 0 << endl << layers << endl <<
    xsize << endl << ysize << endl << xstart << endl << ystart << endl;

  for (int i = 0; i < ndevices; i++)
    {
      devices[i]->print ();
      devices[i]->make ();
    };

};
