
use strict;
use XML::Parser;

my $fileName = $ARGV[0];
my $outName = $ARGV[1];

help($fileName) unless (-f $fileName && length($outName));

my @output;
my $intend = 0;

$fileName =~ /(.*)(\.[^.]*)$/;

my $file = $1;
my $ext = $2;

if($ext =~ /\.dui$/)
	{
	open(DUI, "$fileName") or die "Cannot open $file: $!\n";
	while(<DUI>)
		{
		open($_);
		}
	close(DUI);
	}
else
	{
	duiml($fileName);
	}

dirgen($file, \@output);

print "$outName done\n";	

sub duiml
	{
  my $file = shift;
   
	my $parser = new XML::Parser(	Handlers => {Start => \&handleStart,
	                             	End   => \&handleEnd,
	                             	Comment => \&handleComment});
	
	
	$parser->parsefile($file);
	}
	
sub handleStart
	{
 	my $p = shift;
 	my $e = shift;
 	
 	print_int($intend);
 	
 	if($e eq "container")
  	{
  	$intend++;
  	$e = "containerstart";
  	}
  elsif($e eq "view")
  	{
  	die "Invalid tag \"view\" here\n" unless $intend == 0;
  	$intend++;
  	$e = "viewstart";
  	}
  elsif($e eq "dui")
  	{
  	out("dui-1\n");
  	return;
  	}
 	
 	
 	out("$e:");
 	while(1)
 		{
 		my $param = shift;
 		last unless defined($param);
 		my $value = shift;
 		die "Invalid param for $param\n" unless defined($value);
 		out(" $param = \"$value\"");
 		}
 	out("\n");
  }
	
sub handleEnd
	{
  my ($p, $e)= @_;
  my $tag;
  if($e eq "container")
  	{
  	die "Invalid tag \"view\" here\n" unless $intend > 0;
  	$intend--;
  	$tag = "containerend";
  	}
  elsif($e eq "view")
  	{
  	die "Invalid tag \"view\" here\n" unless $intend == 1;
  	$intend--;
  	$tag = "viewend";
  	}
  elsif($e eq "dui")
  	{
  	return;
  	}
  else
  	{
  	return;
  	}
  print_int($intend);
 	out("$tag:\n");
}  



sub handleComment
	{
  my ($p, $c )= @_; 
  out("#$c\n");
  }    
  
sub print_int
	{
	my $int = shift;
	while($int--)
		{
		out("    ");
		}
	}
	
sub out
	{
	push(@output, shift);
	}	

sub dirgen
{
my ($fname, $lines) = @_;
my @filenames;
my $path;
my $localname;
if($fname =~ /(.*)[\/|\\](.*)$/)
	{
	$path = $1;
	$localname = $2;
	}
else
	{
	$path = ".";
	$localname = "$fname";
	}

push(@filenames, "$localname.dui");


foreach my $ln (@$lines)
	{
	next if($ln =~ /^#/);
	my $line = $ln;
	while($line =~ /\"([^\"]*)\"/)
		{
		my $match = $1;
		$line = $'; #'
		push(@filenames, $match) if(-f "$path/$match");
		}
	}

my @data;	
my @datasizes;
my $datacount;

foreach my $filename (@filenames)
	{
	open(BIN, "$path/$filename") or die "Cannot open data $filename: $!\n";
	binmode(BIN);
	my $filedata = do { local $/; <BIN> };
	push(@data, \$filedata);
	push(@datasizes, length($filedata));
	close(BIN);
	$datacount++;
	}	
# content structure
# content := id datas;
#	data := data datas
# data := filename_size filename file_size filedata

die "File $outName should have a \".dir\" extension " unless $outName =~ /\.dir$/;
die "File $outName already exists" unless -f $outName;
 
open(OUT, ">$outName") or die "Cannot open out $outName: $!\n";
binmode(OUT);
print OUT "DIRF";
print OUT pack("S", 1);
print OUT pack("S", 0);
print OUT  pack("i",$datacount);
for(my $i = 0; $i < $datacount; $i++)
	{
	print OUT  pack("i", length($filenames[$i]));
	print OUT $filenames[$i];
	print OUT  pack("i", $datasizes[$i]);
	my $dataptr = $data[$i];
	print OUT $$dataptr;
	}
close(OUT);
}

sub help
	{
	my $name = shift;
	print "duimlc, DUIML compiler\n";
	print "Copyright Markus Mertama 2006\n";
	print "use: perl duimlc.pl DUIMLFILE DIRFILE\n dirfile DIRFILE is generated into current directory\n\n";
	die "Cannot open  $name:$!\n";
	}


