#! /usr/bin/perl

use strict;
use warnings;

if( @ARGV < 4 ) {
  print( STDERR "usage: $0 <pins> <body width (mm)> <pwr pad length (mm)> <pwr pad width (mm)>\n" );
  exit( -1 );
}
my $pins = int( abs( $ARGV[0] ) );
my $body_width = abs( $ARGV[1] );
my $pwr_pad_length = abs( $ARGV[2] );
my $pwr_pad_width = abs( $ARGV[3] );

my $pin_dist = 0.65;
my $pad_inner_ext = 0.775;
my $pad_outer_ext = 0.775;
my $pad_width = 0.25;

my $silk_dist = 0.254;

my $pcb_clearance = 3000;
my $pcb_solder_add = 600;

my $arc_rad = 0.635;
my $pcb_silk_width = 700;

my $pins_side = int( $pins / 2 );
if( $pins_side * 2 != $pins ) {
  print( STDERR "number of pins not divisble by 2\n" );
  exit( -1 );
}

sub mm2pcb
{
  my $mm = shift;
  my $pcb = $mm / 0.000254;
  my $pcb_i = $pcb < 0 ? int( $pcb - 0.5 ) : int( $pcb + 0.5 );
  return $pcb_i;
}

sub pad
{
  my ($x1, $y1, $x2, $y2, $no) = @_;
  my $dx = abs( $x2 - $x1 );
  my $dy = abs( $y2 - $y1 );
  my $width = $dx < $dy ? $dx : $dy;
  my $width2 = $width / 2;
  my $cx = ($x1 + $x2) / 2;
  my $cy = ($y1 + $y2) / 2;
  my $dx1 = $x1 - $cx;
  my $dx2 = $x2 - $cx;
  my $dy1 = $y1 - $cy;
  my $dy2 = $y2 - $cy;
  $x1 += $dx1 < 0 ? $width2 : -$width2;
  $x2 += $dx2 < 0 ? $width2 : -$width2;
  $y1 += $dy1 < 0 ? $width2 : -$width2;
  $y2 += $dy2 < 0 ? $width2 : -$width2;
  my $pcb_width = mm2pcb( $width );
  printf( "\tPad[%d %d %d %d %d %d %d \"%d\" \"%d\" \"square\"]\n",
          mm2pcb( $x1 ), mm2pcb( $y1 ),
          mm2pcb( $x2 ), mm2pcb( $y2 ),
          $pcb_width, $pcb_clearance,
          $pcb_width + $pcb_solder_add,
          $no, $no );
}

sub line
{
  my ($x1, $y1, $x2, $y2) = @_;
  printf( "\tElementLine[%d %d %d %d %d]\n",
          mm2pcb( $x1 ), mm2pcb( $y1 ),
          mm2pcb( $x2 ), mm2pcb( $y2 ),
          $pcb_silk_width );
}

sub arc
{
  my ($x, $y, $w, $h, $start, $angle) = @_;
  printf( "\tElementArc[%d %d %d %d %d %d %d]\n",
          mm2pcb( $x ), mm2pcb( $y ),
          mm2pcb( $w ), mm2pcb( $h ),
          $start, $angle,
          $pcb_silk_width );
}

my $d_ver = ($pins_side - 1) * $pin_dist / 2 + $pad_width / 2;
my $d_outer = $body_width / 2 + $pad_outer_ext;
my $d_inner = $body_width / 2 - $pad_inner_ext;

my $d_outline_ver = $d_ver + $silk_dist;
my $d_outline_hor = $d_outer + $silk_dist;

printf( "Element[\"\" \"PDSO%d\" \"IC1\" \"PDSO%d\"" .
        " 0 0 %d %d 0 100 \"\"]\n(\n",
        $pins, $pins,
        mm2pcb( -$d_outline_hor ),
        mm2pcb( $d_outline_ver ) + 1000 );

for( my $i = 0; $i < $pins_side; $i++ ) {
  my $y = ($i - ($pins_side - 1) / 2) * $pin_dist;
  my $y1 = $y - $pad_width / 2;
  my $y2 = $y + $pad_width / 2;
  pad( -$d_outer, $y1, -$d_inner, $y2, 1 + $i );
  pad( $d_outer, $y1, $d_inner, $y2, $pins - $i );
}

pad( -$pwr_pad_width / 2, -$pwr_pad_length / 2,
     $pwr_pad_width / 2, $pwr_pad_length / 2, $pins + 1 );

line( -$d_outline_hor, -$d_outline_ver, -$arc_rad, -$d_outline_ver );
line( $d_outline_hor, -$d_outline_ver, $arc_rad, -$d_outline_ver );
arc( 0, -$d_outline_ver, $arc_rad, $arc_rad, 0, 180 );
line( -$d_outline_hor, $d_outline_ver, $d_outline_hor, $d_outline_ver );
line( -$d_outline_hor, -$d_outline_ver, -$d_outline_hor, $d_outline_ver );
line( $d_outline_hor, -$d_outline_ver, $d_outline_hor, $d_outline_ver );

print( "\t)\n" );