#!/bin/sh
#   fp2preview - convert a library footprint to preview image
#   Copyright (C) 2015,2019 Tibor 'Igor2' Palinkas
#
#   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.,
#   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#   http://repo.hu/projects/pcb-rnd


# depends on the diag and the autocrop plugins

photo=0
grid_unit="mil"
dpi=600
outfile=fp2preview.png

annotation=pins

while test $# -gt 0
do
	case "$1" in
		--outfile) outfile="$2"; shift 1;;
		--dpi) dpi="$2"; shift 1;;
		--photo|p) photo=1;;
		--grid-unit|g) grid_unit="$2"; shift 1;;
		--mm) grid_unit="mm";;
		--annotation) annotation="$2"; shift 1;;
		*)
			if test ! -z "$fp"
			then
				echo "only one footprint name is accepted; got: '$fp' and '$1'" >&1
				exit 1
			else
				fp="$1"
			fi
	esac
	shift 1
done

rfp=`realpath $fp`

echo '
	DumpLibFootprint("'$fp'", origin, bbox);
' | pcb-rnd --gui batch | awk -v "fp=$rfp" -v grid_unit=$grid_unit -v "outfile=$outfile" -v "dpi=$dpi" -v "annotation=$annotation" -v "photo=$photo" '

BEGIN {
	q="\""
	dim_arrow_len = 0.7
	if (annotation ~ "pins")
		enable_pinnum = 1
	if (annotation ~ "dimname")
		enable_dim_name = 1
	if (annotation ~ "dimvalue")
		enable_dim_value = 1
	dims = 0
}


/^[ \t]*#dimension/ {
	if ((enable_dim_name) || (enable_dim_value)) {
		DIM[dims, "x1"] = $2*0.0254
		DIM[dims, "y1"] = $3*0.0254
		DIM[dims, "x2"] = $4*0.0254
		DIM[dims, "y2"] = $5*0.0254
		DIM[dims, "dist"] = $6*0.0254
		DIM[dims, "name"] = $7
		DIM[dims, "val"] = $8
		dims++
	}
}

/^<DumpLibFootprint> error/ { exit(1) }
/^<DumpLibFootprint> bbox mm/ { bbx1 = $4; bby1 = $5; bbx2 = $6; bby2 = $7; }
/^<DumpLibFootprint> origin mm/ { ox = $4; oy = $5; }

function line(layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags)
{
	if (Clearance == "") Clearance = 0;
	if (Thickness == "") Thickness = 1;
	print "LineNew(noundo, pcb, " layer "," X1 "mm," Y1 "mm," X2 "mm," Y2 "mm," Thickness "," Clearance "mm," q "clearline" q ")"
}

function text(layer, x, y, rot, scale, thickness, text_string)
{
	print "TextNew(noundo, pcb, " layer ", 0, " x "mm," y "mm," rot "," scale "," thickness "," q text_string q ", clearline)"
}

function unit_txt(s)
{
	if ((s < 0.001) && (s > -0.001))
		return "0 " grid_unit
	if (grid_unit == "mil")
		return sprintf("%.2f mil", s/0.0254)
	else
		return sprintf("%.2f mm", s)
}


function annot(x, y, txt, rot, elev, hcenter    ,sx,sy)
{
	sx = length(txt)*0.5
	sy = 1.2
	if (rot)
		text("#0", x-sy, y-sx/2, 90, 70, 1, txt)
	else
		text("#0", x-sx/2, y-sy, 0, 70, 1, txt)
}

function dimension(x1, y1, x2, y2, dist, name, value     ,vx,vy,nx,ny,X1,Y1,X2,Y2,len,alen,awidth,tmp, ang,negdist,cx,cy,dx,dy,D)
{
	alen = dim_arrow_len

	vx = x2-x1
	vy = y2-y1
	len = vx*vx+vy*vy
	if (len == 0)
		return
	len = sqrt(len)
	vx = vx/len
	vy = vy/len
	nx = vy
	ny = -vx

	if (dist ~ "^[@]") {
		cx = (x1+x2)/2
		cy = (y1+y2)/2
		sub("@", "", dist)
		split(dist, D, ";")
		nx = D[1] - cx
		ny = D[2] - cy

		X1 = x1+nx
		Y1 = y1+ny
		X2 = x2+nx
		Y2 = y2+ny

		dist = nx*nx+ny*ny
		if (dist > 0)
			dist = sqrt(dist)

		nx /= dist
		ny /= dist
	}
	else {
		if (dist < 0) {
			tmp = x1
			x1 = x2
			x2 = tmp
			tmp = y1
			y1 = y2
			y2 = tmp
			dist = -dist

			vx = -vx
			vy = -vy
			nx = -nx
			ny = -ny
		}

		X1 = x1+nx*dist
		Y1 = y1+ny*dist
		X2 = x2+nx*dist
		Y2 = y2+ny*dist
	}


	if (alen > len/4)
		alen=len/4

	awidth=alen/6

	ang = atan2(vx, vy)


	line("#0", x1, y1, X1+nx*awidth, Y1+ny*awidth, "0.1mm")
	line("#0", x2, y2, X2+nx*awidth, Y2+ny*awidth, "0.1mm")
	line("#0", X1, Y1, X2, Y2, "0.1mm")
	
#arrowheads
	line("#0", X1, Y1, X1+vx*alen+nx*awidth, Y1+vy*alen+ny*awidth, "0.1mm")
	line("#0", X1, Y1, X1+vx*alen-nx*awidth, Y1+vy*alen-ny*awidth, "0.1mm")
	line("#0", X2, Y2, X2-vx*alen+nx*awidth, Y2-vy*alen+ny*awidth, "0.1mm")
	line("#0", X2, Y2, X2-vx*alen-nx*awidth, Y2-vy*alen-ny*awidth, "0.1mm")

	if (enable_dim_value) {
		if (value == "")
			value = len
		else if (value == "!")
			value = ""
		if (value != "")
			value = unit_txt(value)
	}
	else
		value = ""

	if (!enable_dim_name)
		name = ""

	if ((name != "") && (value != ""))
		name = name "=|" value
	else if ((value != "") && (name == ""))
		name = value

	if (name != "") {
		if (ang < 0)
			ang = -ang
		if ((ang < 3.1415*3/4) && (ang > 3.1415*1/4))
			annot((X1+X2)/2, (Y1+Y2)/2, name, 0, awidth*1.1,0)
		else
			annot((X1+X2)/2, (Y1+Y2)/2, name, 1, awidth*1.1,0)
	}
}

END {
	if (grid_unit == "mil")
		grid = 2.54;
	else
		grid = 1;

	margin = grid*2

	print "LoadFrom(SubcToBuffer, " q  fp q ")"
	print "PasteBuffer(ToLayout, " (-1*bbx1+ox)+margin ", " (-1*bby1+oy)+margin ", mm)"

	# draw the grid
	x1 = (ox-bbx1-margin) - int((ox-bbx1-margin)) * grid
	y1 = (oy-bby1-margin) - int((oy-bby1-margin)) * grid
	for(y = y1; y < bby2-bby1+margin*1.5; y +=grid) {
		to=bbx2-bbx1+margin*1.5
		line("#1", x1, y, to, y);
		text("#1", to+0.75, y-0.75, 0, 70, 1, unit_txt(y+bby1-oy-margin))
	}

	for(x = x1; x < bbx2-bbx1+margin*1.5; x +=grid) {
		line("#1", x, y1, x, bby2-bby1+margin*1.5);
		text("#1", x-0.75, to+5, 90, 70, 1, unit_txt(x+bbx1-ox-margin))
	}

	dx = -bbx1+margin
	dy = -bby1+margin

	for(n = 0; n < dims; n++) {
		dimension(DIM[n, "x1"]+dx, DIM[n, "y1"]+dy, DIM[n, "x2"]+dx, DIM[n, "y2"]+dy, DIM[n, "dist"], DIM[n, "name"], DIM[n, "val"]);
	}

	if (enable_pinnum) {
		print "query(select, \"@.type==SUBC||@.type==PSTK\")"
		print "propset(selection, p/flags/termname, 1)"
		print "query(unselect, @)"
	}

	if (photo) {
		photo = "--photo-mode, "
	}
	else
		photo = ""
	print "autocrop()"
	print "Export(png, --dpi, " dpi ", --as-shown, " photo " --outfile, " q outfile q ")"
	print "Save(LayoutAs, \"A.lht\")"
}

' | pcb-rnd --gui batch
