#!/usr/bin/perl

use strict;
use warnings;

#print "Content-type: text/html\n\n";

use XML::XPath;
use XML::XPath::XMLParser;
use GD;
use GD::Polyline;
use GD::Simple;
use CGI;
use CGI::Session;

my $query = new CGI;   

my $sid = $query->param("CGISESSID") || undef;

my $session = new CGI::Session( $sid );

 
my $svg = $query -> param( 'svg' );
my $id;

if ( $svg ) {

	print $session->header();

	$id = rand();
	$session -> param( $id, $svg );
	
	my $sid = $session->id();

	print "id=$id";

} else {


	$id = $query -> param( 'id' );

	my $xp = XML::XPath -> new ( xml => ($session -> param( $id ) ) );
	my $viewBox = $xp -> find( '/svg/@viewBox' );	
	
	my ($minX, $minY, $width, $height) = $viewBox =~ /([-\d]+) ([-\d]+) ([-\d]+) ([-\d]+)/;
	
	#SVG includes concept of negative numbers in point list. To create valid
	#points for GD (which allows only positive), we must add the difference between 0 and the minX or minY value 
	#to each point in the line being drawn. This is stored in xOffset and yOffset.
	my $xOffset = 0 - $minX;
	my $yOffset = 0 - $minY;
	
	if ( $minX < 0 ) { $xOffset = abs( $minX ); }
	if ( $minY < 0 ) { $yOffset = abs( $minY ); }				
	
	my $dAttribute = $xp -> find( '/svg/path/@d' ); 
	my $strokeAttribute = $xp -> find( '/svg/path/@stroke' ); 
	
	#structure of "d" attribute is single letter followed by pairs of numbers, eg: "M 100 200 L 200 300 120 150"
	my %commandHash = $dAttribute =~ /([A-Z])(.*)([A-Z])(.*)/;
		
	#commence actual drawing of polyline.
	my $im = new GD::Image( $width, $height );
	
	my $white = $im->colorAllocate( 255, 255, 255 );
	$im -> transparent( $white );
	
	my $blue = $im->colorAllocate( 0, 0, 255 );
	
	$im -> setThickness( 4 );
	
	#SVG's "moveto" command becomes first point in our line, and base case of loop below
	my ($lastX, $lastY) = split( ' ', $commandHash{ "M" } );

	$lastX = $lastX + $xOffset;
	$lastY = $lastY + $yOffset;

	my @polyLinePts = split( ' ', $commandHash{ "L" } );
	
	my $isPairComplete = 0;		
	my $lastElement = 0;		
	
	foreach( @polyLinePts ) {
	
		if ( $isPairComplete ) {	
			
			my $thisX = $lastElement;
			my $thisY = $_;
			
			$thisX = $thisX + $xOffset;
			$thisY = $thisY + $yOffset;
			
			$im -> line( $lastX, $lastY, $thisX, $thisY, $blue );				
		
			$lastX = $thisX;
			$lastY = $thisY;
			$lastElement = 0;
			$isPairComplete = 0;
	
		} else {
	
			$lastElement = $_;
			$isPairComplete = 1;
		
		}
	
	}
		
	print "Content-type: image/gif\n\n";
	print $im->gif;
}

