# run this "perl -w cardfull.pl" it will output the postscript to
# "card.ps". it will output the more concise version of the code
# (which is what's on the card) to "card.pl". to test the code that
# appears on the card, you can run "perl card.pl" and notice how it
# generates the same postscript

#todo: dont use the ps module at all
# fix the lumpy shape
# color
# more style on the RHS text
# bigger program text
# interesting background


use PostScript::Simple;

$p = new PostScript::Simple(landscape=>0,
			    xsize=>3.5*72,
			    ysize=>2*72,
			    eps=>1,
			    papersize=>"a4",
			    colour=>1,
			    units=>"pt");


$p->box(0,0,3.5*72,2*72);



# write the easy text on the right
$p->setfont("Times-Roman", 10);

for $ty (['Drew Perttula',78],
	['510-841-1265',50],
	['http://bigasterisk.com',32],
	['drewp@bigasterisk.com',24],
	['Card code at http://bigasterisk.com/card',8]
	) {
  @l=@$ty;
  $p->text(245,$l[1],$l[0],'right');
  $p->setfont("Times-Roman",7) if $l[1]==78
}

# arcs:
# x-coord y-coord r ang1 ang2 arc (ccw)
# x-coord y-coord r ang1 ang2 arcn (cw)

#$p->{pspages}.="gsave 3 u setlinewidth .8 setgray newpath 246 u 72 u moveto 160 u 72 u lineto 75 u 72 u 80 u 0 55 arc 75 u 72 u 80 u 55 -55 arcn stroke grestore\n";

$p->{pspages}.="gsave 3 u setlinewidth .8 setgray newpath 246 u 72 u moveto 156 u 72 u lineto stroke\n";
$p->{pspages}.="173 u 119 u moveto 165 u 17 u lineto 123 u 25 u lineto 114 u 37 u lineto 103 u 34 u lineto 109 u 23 u lineto 102 u 22 u lineto 97 u 30 u lineto 85 u 28 u lineto 94 u 14 u lineto 72 u 12 u lineto 72 u 126 u lineto closepath clip newpath "              ."122 u 110 u moveto 190 u 100 u 165 u 24 u 80 u 22 u curveto "              ."80 u 23.5 u lineto 160 u 24 u 180 u 100 u 121 u 102 u curveto "              ."closepath fill grestore\n";


# some params for the shape
$xc=75; $yc=72; # shape center
$p->setfont("Courier", 2.9); #Times-Roman #2.7/1.374/fs-.24
$letterspacing=1.320;
$cornerspace=.6; # outer (convex) corners only
$fd=-.24; # how far do we move in on each spiral level

# read this code from disk
open(IN,"cardfull.pl");
$code=join("",<IN>);

#STRIP
# some unneeded sections of the code (like this one) will be dropped
$code=~s/\#STRIP.*?END[S]TRIP//sg;
# cut all comments
$code=~s/#[^\!].*//mg;
#join lines
$code=~s/\n/ /g;
$code=~s/cardfull.pl/card.pl/; # result needs to read itself, not this version
#condense whitespace
$code=~s/\s+/ /g;
$code=~s/([[:punct:]]) ([[:punct:]])/$1$2/g; # never spaces between punctuation
$code=~s/\( /\(/g; $code=~s/ \)/\)/g; # don't need spaces within parens
# abbreviate some names :(
$code=~s/polartocart/ptc/g;
$code=~s/letters/ltr/g;
$code=~s/cornerspace/csp/g;
$code=~s/letterspacing/lsp/g;
$code=~s/outer/f1/g;
$code=~s/inner/f2/g;
#save a copy for review and testing
open(OUT,">card.pl");
print OUT $code;
#ENDSTRIP

$f=1;
$start=0;
while($f>0) {
  for $i (0..5) {
    $ang=(($i+1)%6)*60+2;
    # out
    letters( inner(-1,$f), outer(-1),                 $ang,    $cornerspace ) if $start++;
    # cross
    letters( outer(-1),    outer(1),                  $ang+90, $cornerspace*5 );
    # in
    letters( outer(1),     inner(1,$f+($fd*($i==5))), $ang+180,$cornerspace );
  }
  $f+=$fd;
}

#STRIP
print "didn't finish the code! ",length($code)," chars left\n" if $code;
#ENDSTRIP

$p->output("card.ps");

# macros to return coordinates of inner and outer points on the shape
sub outer {
  my($side)=$_[0];
  return polartocart( 58+14*$f, $ang + $side*(2+10*$f) );
}
sub inner {
  my($side,$f)=@_;
  return polartocart( 5+24*$f, $ang + $side*30 );
}
sub polartocart {
  my( $r, $deg )=@_;
  return ($xc+$r*cos($deg*.017453),$yc+$r*sin($deg*.017453));
}

sub letters {
  my($x1,$y1,$x2,$y2,$ang,$cornerspace)=@_;
  my($dx,$dy,$d,$x,$y);

  $dx = $x2-$x1;
  $dy = $y2-$y1;
  $d = sqrt($dx**2+$dy**2);

  $x=$x1; $y = $y1;

  $x+=$dx/$d*$cornerspace;
  $y+=$dy/$d*$cornerspace;

  while( abs($x-$x1)<abs($dx)-$cornerspace || abs($y-$y1)<abs($dy)-$cornerspace ) {

    if( $code=~s/^(.)// ) {
      $char=$1;
      $char = "\\$char" if $char=~/[\(\)\\]/;
      $p->{pspages}.="gsave $x u $y u moveto $ang rotate ($char) show grestore\n";
    }
    $x+=$letterspacing*$dx/$d;
    $y+=$letterspacing*$dy/$d;

  }
}




