/*
 GerberConversion
 Copyright (C) 2010 Martin Štrympl
 
 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 3.0 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.
 
 Martin Štrympl
 xstrym00@stud.feec.vutbr.cz
 */

#include "Dcodes.h"

#include "Gerber.h"

#define MY_PI (3.141592653589793L)

Mac_Fun_Dcode_Dcodes_Dcode(Dcode_Circle)
{
  int s4_ret;
  struct sGerber_Point s_A, s_B;
  
  //s_A=ps_actual->s_xy.s_new;
  if (!RealPoint(ps_actual, &s_A, &ps_actual->s_xy.s_new))
  {
    printf("Transform old point from axis X and Y to axis A and B failed.\n");
    return -1;
  }
  s_B=s_A;
  s4_ret=Gerber_Gerber_OvalSegment(ps_gerber, &s_A, pu_data->s_circle.ld_diameter/2.0L, pu_data->s_circle.ld_diameter/2.0L, 0.0L, 360L, false);
  if (s4_ret!=0) return s4_ret;
  
  if ((abs(pu_data->s_circle.ld_xhole)>0.0000001L)&&(abs(pu_data->s_circle.ld_yhole)>0.0000001L))
  {
    if (abs(pu_data->s_circle.ld_yhole)>0.0000001L)
    {
      //struct sGerber_Point s_A, s_B;
      long double ld_changeX, ld_changeY;
      
      ld_changeX=pu_data->s_circle.ld_xhole/2.0L;
      ld_changeY=pu_data->s_circle.ld_xhole/2.0L;
      
      //s_A=ps_actual->s_xy.s_new;
      //s_B=ps_actual->s_xy.s_new;
      
      s_A.ld_x+=ld_changeX;
      s_A.ld_y+=ld_changeY;
      s_B.ld_x+=ld_changeX;
      s_B.ld_y-=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
      
      ld_changeX+=ld_changeX;
      ld_changeX+=ld_changeX;
      s_B.ld_x-=ld_changeX;
      s_B.ld_y+=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
      
      s_A.ld_x-=ld_changeX;
      s_A.ld_y-=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
      
      s_B.ld_x+=ld_changeX;
      s_B.ld_y-=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
    }
    else
    {
      //s_A=ps_actual->s_xy.s_new;
      s4_ret=Gerber_Gerber_OvalSegment(ps_gerber, &s_A, pu_data->s_circle.ld_xhole/2.0L, pu_data->s_circle.ld_xhole/2.0L, 0.0L, 360L, false);
    }
  }
  return s4_ret;
}
Mac_Fun_Dcode_Dcodes_Dcode(Dcode_Rectangle)
{
  int s4_ret;
  struct sGerber_Point s_A, s_B;
  long double ld_changeX, ld_changeY;
  
  ld_changeX=pu_data->s_rectange.ld_x/2.0L;
  ld_changeY=pu_data->s_rectange.ld_y/2.0L;
  
  if (!RealPoint(ps_actual, &s_A, &ps_actual->s_xy.s_new))
  {
    printf("Transform old point from axis X and Y to axis A and B failed.\n");
    return -1;
  }
  s_B=s_A;
  
  s_A.ld_x+=ld_changeX;
  s_A.ld_y+=ld_changeY;
  s_B.ld_x+=ld_changeX;
  s_B.ld_y-=ld_changeY;
  s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
  if (s4_ret!=0) return s4_ret;
  
  ld_changeX+=ld_changeX;
  ld_changeX+=ld_changeX;
  s_B.ld_x-=ld_changeX;
  s_B.ld_y+=ld_changeY;
  s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
  if (s4_ret!=0) return s4_ret;
  
  s_A.ld_x-=ld_changeX;
  s_A.ld_y-=ld_changeY;
  s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
  if (s4_ret!=0) return s4_ret;
  
  s_B.ld_x+=ld_changeX;
  s_B.ld_y-=ld_changeY;
  s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
  if (s4_ret!=0) return s4_ret;
  
  
  return 0;
}
Mac_Fun_Dcode_Dcodes_Dcode(Dcode_Oround)
{
  int s4_ret;
  struct sGerber_Point s_A, s_B;
  
  //s_A=ps_actual->s_xy.s_new;
  if (!RealPoint(ps_actual, &s_A, &ps_actual->s_xy.s_new))
  {
    printf("Transform old point from axis X and Y to axis A and B failed.\n");
    return -1;
  }
  s_B=s_A;
  s4_ret=Gerber_Gerber_OvalSegment(ps_gerber, &s_A, pu_data->s_oround.ld_x/2.0L, pu_data->s_oround.ld_y/2.0L, 0.0L, 360L, false);
  if (s4_ret!=0) return s4_ret;
  
  if ((abs(pu_data->s_oround.ld_xhole)>0.0000001L)&&(abs(pu_data->s_oround.ld_yhole)>0.0000001L))
  {
    if (abs(pu_data->s_oround.ld_yhole)>0.0000001L)
    {
      //struct sGerber_Point s_A, s_B;
      long double ld_changeX, ld_changeY;
      
      ld_changeX=pu_data->s_oround.ld_xhole/2.0L;
      ld_changeY=pu_data->s_oround.ld_xhole/2.0L;
      
      //s_A=ps_actual->s_xy.s_new;
      //s_B=ps_actual->s_xy.s_new;
      
      s_A.ld_x+=ld_changeX;
      s_A.ld_y+=ld_changeY;
      s_B.ld_x+=ld_changeX;
      s_B.ld_y-=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
      
      ld_changeX+=ld_changeX;
      ld_changeX+=ld_changeX;
      s_B.ld_x-=ld_changeX;
      s_B.ld_y+=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
      
      s_A.ld_x-=ld_changeX;
      s_A.ld_y-=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
      
      s_B.ld_x+=ld_changeX;
      s_B.ld_y-=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
    }
    else
    {
      //s_A=ps_actual->s_xy.s_new;
      s4_ret=Gerber_Gerber_OvalSegment(ps_gerber, &s_A, pu_data->s_oround.ld_xhole/2.0L, pu_data->s_oround.ld_xhole/2.0L, 0.0L, 360L, false);
    }
  }
  return s4_ret;
}
Mac_Fun_Dcode_Dcodes_Dcode(Dcode_Regular)
{
  int s4_ret;
  struct sGerber_Point s_A, s_B, s_center;
  uint32_t u4_n;
  long double ld_agle, ld_step;
  
  //s_A=ps_actual->s_xy.s_new;
  if (!RealPoint(ps_actual, &s_center, &ps_actual->s_xy.s_new))
  {
    printf("Transform old point from axis X and Y to axis A and B failed.\n");
    return -1;
  }
  //s_B=s_A;
  //s4_ret=Gerber_Gerber_OvalSegment(ps_gerber, &s_A, pu_data->s_oround.ld_x/2.0L, pu_data->s_oround.ld_y/2.0L, 0.0L, 360L, false);
  //if (s4_ret!=0) return s4_ret;
  ld_agle=(pu_data->s_regular.ld_agleStart/180.0L)*MY_PI;
  s_B.ld_x=cos(ld_agle);
  s_B.ld_y=sin(ld_agle);
  ld_step=(2.0L*MY_PI)/pu_data->s_regular.u4_sides;
  for (u4_n=1;u4_n<pu_data->s_regular.u4_sides;u4_n++)
  {
    s_A=s_B;
    ld_agle+=ld_step;
    
    s_B.ld_x=cos(ld_agle);
    s_B.ld_y=sin(ld_agle);
    
    s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
    if (s4_ret!=0) return s4_ret;
  }
  
  if ((abs(pu_data->s_oround.ld_xhole)>0.0000001L)&&(abs(pu_data->s_oround.ld_yhole)>0.0000001L))
  {
    if (abs(pu_data->s_oround.ld_yhole)>0.0000001L)
    {
      //struct sGerber_Point s_A, s_B;
      long double ld_changeX, ld_changeY;
      
      ld_changeX=pu_data->s_oround.ld_xhole/2.0L;
      ld_changeY=pu_data->s_oround.ld_xhole/2.0L;
      
      //s_A=ps_actual->s_xy.s_new;
      //s_B=ps_actual->s_xy.s_new;
      
      s_A.ld_x+=ld_changeX;
      s_A.ld_y+=ld_changeY;
      s_B.ld_x+=ld_changeX;
      s_B.ld_y-=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
      
      ld_changeX+=ld_changeX;
      ld_changeX+=ld_changeX;
      s_B.ld_x-=ld_changeX;
      s_B.ld_y+=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
      
      s_A.ld_x-=ld_changeX;
      s_A.ld_y-=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
      
      s_B.ld_x+=ld_changeX;
      s_B.ld_y-=ld_changeY;
      s4_ret=Gerber_Gerber_LineSegment(ps_gerber, &s_A, &s_B, false);
      if (s4_ret!=0) return s4_ret;
    }
    else
    {
      //s_A=ps_actual->s_xy.s_new;
      s4_ret=Gerber_Gerber_OvalSegment(ps_gerber, &s_A, pu_data->s_oround.ld_xhole/2.0L, pu_data->s_oround.ld_xhole/2.0L, 0.0L, 360L, false);
    }
  }
  return s4_ret;
}
