/*
 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
 */

/*
 *  Settings.c
 *  GerberConversion
 *
 *  Created by Martin Štrympl on 11/8/10.
 *  Copyright 2010 School. All rights reserved.
 *
 */

#include "Settings.h"

#include "Gerber.h"

bool RealPoint(struct sGerber_Gerber_Actual *ps_actual, struct sGerber_Point *ps_new, struct sGerber_Point *ps_old)
{  
  /*
   *  q: Image Rotation
   *  n: Image Offset
   *
   *  r:Rotare // layer
   *
   *  
   *  a:Axis select
   *  s:Scale factor // for A or B axis
   *  o:Offset // with A or B axis
   *  m:Mirror Image
   *  i:Mode, Inch or millimeters, default outputs is millimeters
   */
  struct sGerber_Point s_new;
  uint32_t u4_n;
  
  s_new=*ps_old;
  
  for (u4_n=0;u4_n<PRIORITY_LIMIT;u4_n++)
  {
    if (ps_actual->s_sets.at_pointnumeringpriority[u4_n]==0) break;
    
    switch (ps_actual->s_sets.at_pointnumeringpriority[u4_n])
    {
      case 'q': // image rotation
        {
          struct sGerber_Point s_gen;
        
          if (ps_actual->s_ir.u2_rot==0)
          {
            // no changes
            s_gen.ld_x=s_new.ld_x;
            s_gen.ld_y=s_new.ld_y;
          }
          else if (ps_actual->s_ir.u2_rot==90)
          {
            s_gen.ld_x=-s_new.ld_y;
            s_gen.ld_y=s_new.ld_x;
          }
          else if (ps_actual->s_ir.u2_rot==180)
          {
            s_gen.ld_x=-s_new.ld_x;
            s_gen.ld_y=-s_new.ld_y;
          }
          else if (ps_actual->s_ir.u2_rot==270)
          {
            s_gen.ld_x=s_new.ld_y;
            s_gen.ld_y=-s_new.ld_x;
          }
          else
          {
            printf("Program supporting image rotation only about 0, 90, 180 or 270 degrees.\n");
            return false;
          }
          
          s_new=s_gen;
        }
        break;
      case 'n': // image offset
          s_new.ld_x+=ps_actual->s_io.ld_A;
          s_new.ld_y+=ps_actual->s_io.ld_B;
        break;
      /*case 'r':
        break;*/
      case 'a': //axis select
        {
          struct sGerber_Point s_gen;
          
          if (ps_actual->s_as.b_A) s_gen.ld_x=s_new.ld_x;
          else s_gen.ld_x=s_new.ld_y;
          
          if (ps_actual->s_as.b_B) s_gen.ld_y=s_new.ld_x;
          else s_gen.ld_y=s_new.ld_y;
          
          s_new=s_gen;
        }
        break;
      case 's': // scale
          s_new.ld_x*=ps_actual->s_sf.ld_A;
          s_new.ld_y*=ps_actual->s_sf.ld_B;
        break;
      case 'o': // offset
           s_new.ld_x+=ps_actual->s_of.ld_A;
           s_new.ld_y+=ps_actual->s_of.ld_B;
        break;
      case 'm': // mirror image
        if (ps_actual->s_mi.b_A) s_new.ld_x=-s_new.ld_x;
        if (ps_actual->s_mi.b_B) s_new.ld_y=-s_new.ld_y;
        break;
      case 'i': // mode incho or millimeters
          if (ps_actual->s_mo.b_inch)
          {
            if (ps_actual->s_sets.b_millimeters)
            {
              s_new.ld_x*=25.4L;
              s_new.ld_y*=25.4L;
            }
          }
          else
          {
            if (!ps_actual->s_sets.b_millimeters)
            {
              s_new.ld_x/=25.4L;
              s_new.ld_y/=25.4L;
            }
          }
        break;
      default:
        printf("Unknown data for nummering point.\n");
        return false;
    }
  }
  
  *ps_new=s_new;
  
  return true;
}
long double RealDimension(struct sGerber_Gerber_Actual *ps_actual, long double ld_dimension)
{
  if (ps_actual->s_mo.b_inch)
  {
    if (ps_actual->s_sets.b_millimeters)
    {
      return ld_dimension*25.4L;
    }
  }
  else
  {
    if (!ps_actual->s_sets.b_millimeters)
    {
      return ld_dimension/25.4L;
    }
  }
  return ld_dimension;
}
