#!/usr/bin/perl -w
use Cwd;
use Getopt::Long;
use File::Basename;

#
# This script is used to generate the shaded cresent or
# gibbous shapes in a moon icon.  After creating an
# .svg file to represent the moon, find the path item
# that represent the inner, lighter colored outline
# The center and radius arguments should be based
# on this path.
#
#
# The template will usually include a path with the "d" attribute set to:
#
# d="M __X0__,__Y0__
#    C __X1__,__Y0__ __X2__,__Y2__ __X2__,__Y3__
#    S __X1__,__Y4__ __X0__,__Y4__
#    C __X6__,__Y4__ __X7__,__Y7__ __X7__,__Y3__
#    S __X6__,__Y0__ __X0__,__Y0__
#    z"
#
# The first three points define the arc on the outside edge from the
# the top center at <X0,Y0> through center left <X2,Y3> to bottom center
# <X0,Y4>.  The final two define the terminator (the edge between light
# and dark portions of the moon's surface) from <X0,Y4> through <X7,Y3>
# and ending back at the start.
#
# The first pass at this script listed points X0-11 and Y0-11 but a lot of the
# values were redundant.  The expression above limits it to 5 of each
#
# An additional __OPACITY__ value can be included in the template.
# This controls the shading of an object that would depend on the
# amount of light being reflected off the moon; e.g.: a darker cloud
# image when the moon is new and a lighter one when full.  The resulting
# value will vary from 0.125 at the darkest to 0 for brightest

GetOptions("c=s"=>\$center,
		   "r=i"=>\$radius);

# Slurp the svg template
die "missing icon template" unless $#ARGV == 0;
my $src = $ARGV[0];
die "$src not found" unless -f $src;
{
  local ($/,undef);
  open(T, $src) || die "can't open $src: $!";
  $fmt=<T>;
}

# The "-c" option can be either an "x,y" value
# or just a single numeric ("x,x")

my $x;
my $y;
if ($center =~ /^(\d+),(\d+)$/) {
  $x = $1;
  $y = $2;
} elsif ($center =~ /^(\d+)$/) {
  $y = $x = $1;
} else {
  print "can't parse '-c': should be <n> or <n,n>\n";
}

use constant PI => atan2(1,1)*4;
my $b = $radius * 4/3 * (sqrt(2) - 1.);

my $x0=$x;
my $x1=$x - $b;
my $x2=$x - $radius;

my $y0=$y+$radius;
my $y2=$y + $b;
my $y3=$y;
my $y4=$y-$radius;

$_ = $fmt;

eval s/__X0__/$x0/g;
eval s/__Y0__/$y0/g;
eval s/__Y2__/$y2/g;
eval s/__Y3__/$y3/g;
eval s/__Y4__/$y4/g;

my $pass1=$_;

my $out = basename($src,".svg");
for ($d=0; $d<360; $d+=10) {
  if ($d == 180) {
	$x1=$x+$b;
	$x2=$x+$radius;
  }

  my $name = sprintf "%s_%03d.svg",$out,$d;

  open (D, ">$name") || die "can't open $name: $!";

  my $h= cos( ($d % 180) * PI / 180.);
  my $x6=$x+$h*$b;
  my $x7=$x+$h*$radius;
  my $y7=$y - $b;
  my $opacity = (1+ cos($d * PI / 180.)) / 16.;
  $_=$pass1;

  eval s/__X1__/$x1/g;
  eval s/__X2__/$x2/g;
  eval s/__X6__/$x6/g;
  eval s/__X7__/$x7/g;
  eval s/__Y7__/$y7/g;
  eval s/__OPACITY__/$opacity/g;
  print D;
  close (D);
}
