#!/usr/bin/perl
use strict;

my $wo = $ARGV[0];
my @parts = split("/", $wo);
my $fileName = pop(@parts);
$fileName =~ /(.*?)\.wo/;
$fileName = $1;
# for now, write to /tmp/
open(MODIFIED_WORK_CALENDAR, ">/tmp/$fileName.html") or die "Cannot open .ics file '/tmp/$fileName.html' for writing";
$/ = "\r";
# read all of the HTML and wod into a big string
open SLURP, "$wo/$fileName.html" or die "can't open $wo/$fileName.html: $!"; 
my $html;
while (<SLURP>) {
	$html .= $_;
}

$html =~ s/\r/\n/g;
close SLURP or die "cannot close $wo/$fileName.html: $!"; 
#open SLURP, "$wo/$fileName.html" or die "can't open $wo/$fileName.html: $!"; 
#my $html = <SLURP>; 
#close SLURP or die "cannot close $wo/$fileName.html: $!"; 
if ((-s "$wo/$fileName.html") != length($html)) {
	print("NON-Mac FILE ENCODING.  Exiting...\n");
	exit;
}

open SLURP, "$wo/$fileName.wod" or die "can't open $wo/$fileName.wod: $!"; 
my $wod;
while (<SLURP>) {
	$wod .= $_;
}
close SLURP or die "cannot close $wo/$fileName.wod: $!"; 

# now parse through the wod one block at a time, convert the key-value bindings into WOOgnl format,
# and then replace the declaration in the HTML with the formatted declaration string
$wod =~ s/(\".*?);(.*?\")/$1^^amp^^$2/g;

#also, just in case webobject tags have already been replaced with wo tags...
$html =~ s/(<\/?)wo(\s+[^>]*)?>/$1webobject$2>/gi;
#print $html;
#exit;

$html =~ s/<webobject([^>]*)?\/>/<webobject$1><\/webobject>/sgi;

my %leftoverTypes;
my %leftoverTags;
my @ids;
while ($wod =~ s/(.*?)\s*:\s*(.*?)\s*{\s*(.*?);?\s*}\s*//s) {
	my $declarations = $3;
	#$declarations =~ s/(\".*?);(.*?\")/$1^^amp^^$2/g;
	my @bindings = split(/\s*;\s*/, $declarations);
	my $name = $1;
	#print("$name\n");
	my $type = $2;
	my $finalBinding;

	# now, if the original tag had no id binding, we're going to give it one (we'll just use the name
	# of the binding, which should be unique).  This should make it easier to write tests with
	# Selenium down the line.
	my $hasID = 0;

	foreach my $keyValue (@bindings) {
		#$keyValue =~ s/\s*//g;
#		print("$keyValue\n");
		$keyValue =~ s/\^\^amp\^\^/;/g;
		$keyValue =~ s/^\s+//;
		$keyValue =~ s/\s+$//;
		my ($key, $value) = split("=", $keyValue);
		$key =~ s/\s*//g;
		$value =~ s/^\s+//;
		$value =~ s/\s+$//;
		$value =~ s/\$/\\\$/g;
		#if it doesn't have quotes, it means we've got a variable (unless it's all numeric)
		if ($keyValue !~ /\"/ && $value =~ /\D/) {
			$keyValue = $key . "=" . "\"\$" . $value . "\"";
#			print("$keyValue\n");
			$finalBinding .= $keyValue . " ";
		} else {
#			print($key . "=" . $value ."\n");
			$finalBinding .= $key . "=" . $value . " ";
		}
		if ($key =~ /id/i) {
			$hasID = 1;
		}
	}
	if ($hasID == 0) {
		if ($type =~ /WOForm/i || $type =~ /WOHyperlink/i || $type =~ /WOTextField/i ||
			$type =~ /WOPopUpButton/i || $type =~ /WORadioButton/i || $type =~ /WOText/i ||
			$type =~ /WOSubmitButton/i || $type =~ /WOPasswordField/i || $type =~ /CCGButton/i) {
			$finalBinding .= "id=\"$fileName" . "$name\"";
			push(@ids, $name);
		}
	}
	$html =~ /<webobject\s*name\s*=\s*"?$name"?\s*?>(.*?)<\/webobject>/si;
	if ($1 =~ /.*<webobject.*/si) {
		# there are tags embedded, so we'll do this one later
			$leftoverTypes{$name} = $type;
			$leftoverTags{$name} = "<wo:$type $finalBinding>";
	} else {
		if ($type eq "WOConditional" && $finalBinding =~ /negate\s*=\s*"\$true"/) {
			$finalBinding =~ s/(.*?)\snegate\s*=\s*"\$true"(.*?)/$1$2/;
			$html =~ s/<webobject\s*name\s*=\s*"?$name"?\s*>(.*?)<\/webobject>/<wo:not $finalBinding>$1<\/wo:not>/sgi;
		} else {
			$html =~ s/<webobject\s*name\s*=\s*"?$name"?\s*>(.*?)<\/webobject>/<wo:$type $finalBinding>$1<\/wo:$type>/sgi;
		}
	}
}

#foreach my $key (keys %leftoverTags) {
#		print ("$key -> $leftoverTypes{$key} -> $leftoverTags{$key}\n");
#}
#print("\n\n\n");

# now, loop through the leftovers over and over, always replacing the innermost children until
# we've taken care of all the tags that need replacing
while ((scalar keys %leftoverTypes) > 0) {
	foreach my $name (keys(%leftoverTypes)) {
		#print("$name\n");
		$html =~ /<webobject\s*name\s*=\s*"?$name"?\s*?>(.*?)<\/webobject>/si;
		my $middle = $1;
		if ($middle =~ /.*?<webobject.*?/si) {
			# there are tags embedded, so we'll do this one later
			#print ("$name:  $middle\n\n\n");
			next;
		} else {
#			my $replacement = $leftoverTags{$name} . $middle . "<\/wo:" . $leftoverTypes{$name} . ">";
			#print("<webobject\s*name\\s*=\\s*\"?$name\"?\\s*?>(.*?)<\/webobject>\n");
			#print ("$name:  $replacement\n\n\n");
			$html =~ s/<webobject\s*name\s*=\s*"?$name"?\s*?>(.*?)<\/webobject>/$leftoverTags{$name}$1<\/wo:$leftoverTypes{$name}>/sgi;
			# now remove it from the hash so we can get a parent tag next time
			delete $leftoverTypes{$name};
			delete $leftoverTags{$name};
		}
	}

#	foreach my $key (keys %leftoverTags) {
#		print ("$key -> $leftoverTypes{$key} -> $leftoverTags{$key}\n");
#	}
#	print("\n\n\n");
	
}

#Almost there!  One last little tweak... find all the <wo:...></wo> instances, and convert
# them to shorthand notation, which is a little more readable
$html =~ s/(<wo:([^>]*)?>)\s*<\/wo:.*?>/<wo:$2\/>/g;

#also, get rid of whitespace before a '>', which bugs me
$html =~ s/\s+>/>/g;

#now for more shorthand
$html =~ s/wo:WOForm/wo:form/gi;
$html =~ s/wo:WOString/wo:str/gi;
$html =~ s/wo:WOConditional/wo:if/gi;
$html =~ s/wo:WOHyperlink/wo:link/gi;
$html =~ s/wo:WORepetition/wo:loop/gi;
$html =~ s/wo:WOTextField/wo:textfield/gi;
$html =~ s/wo:WOCheckBox/wo:checkbox/gi;
$html =~ s/wo:WOHiddenField/wo:hidden/gi;
$html =~ s/wo:WOPopUpButton/wo:select/gi;
$html =~ s/wo:WORadioButton/wo:radio/gi;
$html =~ s/wo:WOFileUpload/wo:upload/gi;
$html =~ s/wo:WOText/wo:text/gi;
$html =~ s/wo:WOSubmitButton/wo:submit/gi;
$html =~ s/wo:WOPasswordField/wo:password/gi;

# we were sticking in ID attributes for certain types of fields if they didn't already have them,
# because it makes Selenium testing, writing javascript, etc. easier.  We were using the name
# of the wod binding for this attribute, and so we need to make sure we haven't applied it more than
# once.  This is possible because a wod file binding could be referenced by more than one webobject
# tag in the HTML binding

my $done = 0;
my $retry = 0;
while ($done == 0) {
	my @lines = split($/, $html);
	foreach my $id (@ids) {
		my $instanceCount = 0;
		foreach my $line (@lines) {
			while ($line =~ /"$id"/g) {
				$instanceCount++;
				if ($instanceCount > 1) {
					my $replacement = $id . "_1";
					$html =~ s/id=\"$id\"/id=\"$replacement\"/;
					$retry = 1;
					push(@ids, $replacement);
					last;
				}
			}
			if ($retry == 1) {
			   last;
			}
		}
		if ($retry == 1) {
		   last;
		}
	}
	if ($retry == 1) {
		$retry = 0;
	} else {
		$done = 1;
	}

}

# one last issue (fingers crossed).  We've been sticking ID attributes onto form elements, links,
# etc. as we go so that writing javascript, using Selenium, etc. would be easier.
# However, this is going to be problematic if the thing with an id is in a repetition,
# because then you'll get a bunch of elements with the same id, which will screw everything
# up.  So we're going to do a regex replace to remove ids of every element between <wo:loop> tags
# Sadly, we have to do this over and over as well, to avoid possible issues with nested loops
while ($html =~ /<wo\:loop.*?\sid=".*?".*?<\/wo:loop>/si) {
	$html =~ s/(<wo:loop.*?)\sid=".*?"(.*?<\/wo:loop>)/$1$2/sgi;
}

print($html);