#!/usr/bin/perl

# mi2svg - a perl script for creating svg presentations from mif data.
#
# Copyright (C) 2005, 2006  Research Institute for the Languages of Finland
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
# You may contact the copyright holder by...
#
# ...mail
# 
#   Research Institute for the Languages of Finland
#   Sörnäisten rantatie 25
#   FIN-00500 Helsinki
#
# ...or by e-mail
# 
#   kayttoluvat@kotus.fi
#
#
#
# Author: Toni Ruottu
#

use strict;
use warnings;
use Locale::gettext;
use POSIX;

setlocale(LC_MESSAGES, "");

#bindtextdomain("mi2svg", "po");
textdomain("mi2svg");

use Getopt::Std;
my %options=();
getopts("od:fF",\%options);

my $version = "0.1.6";

# print debug message
#
# param _ - debug message
#
sub print_debug
{
	( $_ ) = @_;

	#if(0==0)
	#{
		printf( gettext( "debug" ) . " - %s", $_ );
	#}
}

# print skipped input line for debug purposes
#
# param input_mode - input mode during the line skip
# param _          - skipped line
# 
sub print_debug_skip
{
	my $input_mode;
	( $input_mode , $_ ) = @_;

	if( ! /^\s*$/ )
	{
		s/\n$//g;

		&print_debug( sprintf(  "(mode: %s) " . gettext( "skipped" ) . " \"%s\"\n" , $input_mode, $_ ) );
	}
}

sub print_debug_split
{
	my $input_mode;
	( $input_mode , $_ ) = @_;

	&print_debug( sprintf( gettext( "MID splitter" ) . " - " . gettext( "error" ) . " -: \"%s\"\n" , $_ ) );

}

# print usage text
#
sub print_usage
{
	printf( STDERR
		"\n  " . gettext("Usage: %s [FILEPREFIX[.mif]]..." ) . "\n\n" .
		"\t(" . gettext("where FILEPREFIX is filename without suffix." ) . ")\n" .
		"\t" . gettext("Converts FILEPREFIX.mif map to FILEPREFIX.svg map." ) . "\n" .
		"\t" . gettext("Includes data fields from FILEPREFIX.mid to SVG as class names." ) . "\n" .
		"\t" . gettext("Accepts multiple input files at once." ) . "\n" .
		"\t" . gettext("Use -f to force overwriting of existing svg." ) . "\n"
	, $0 );
}

# print mi2svg name, short desctiption and legal information
#
sub print_banner
{
	printf( STDERR
		"\nmi2svg %s - " . gettext("a tool for creating svg (Scalable Vector Graphics)" .
		" presentations of maps stored in MapInfo Interchange Format." ) . "\n"
	, $version );
}

# print error message for mif-file opening, proceed to next input file
#
# param filename - Filename of the mif-file that didn't open
#
sub die_mif_file_error
{
	my( $filename ) = @_;

	printf( STDERR
		"\n" . gettext("Could not open file %s" ) . " " . gettext(":-(" ) . "\n".
		"  " . gettext("File not processed..." ) . "\n"
	, $filename );

	die( );
}

# print error message for a mif-file not containing any supported objects,
# proceed to next input file
#
# param filename - Filename of the file with no supported objects
#
sub die_no_objects_error
{
	my( $filename ) = @_;

	printf( STDERR
		"\n" . gettext("File %s.mif did not contain any supported objects" ) . " " . gettext(":-(" ) . "\n".
		"  " . gettext("File not processed..." ) . "\n"
	, $filename );

	die( );
}

# print error message for mid-file opening
#
# param filename - Filename of the mid-file that didn't open
#
sub print_mid_file_error
{
	my( $filename ) = @_;

	printf( STDERR
		"\n" . gettext("Could not open file %s" ) . " " . gettext(":-/" ) . "\n".
		"  " . gettext("File has database information related to the map you are converting" ) . "\n".
		"  " . gettext("If your map has a related MID-file, fix the situation and reconvert\n".
		"  the map." ) . "\n"
	, $filename );


}

# print error message for svg-file opening, proceed to next input file
#
# param filename - Filename of the svg-file that didn't open
#
sub die_svg_file_error
{
	my( $filename ) = @_;

	printf( STDERR
		"\n" . gettext("Could not open file %s" ) . " " . gettext(":-(" ) . "\n" .
		"  " . gettext("Can't write the svg file!" ) . "\n"
	, $filename);

}

# print error message for existing output file, proceed to next input file
#
# param filename - Output filename that already existed
#
sub print_out_file_exists_error
{
	my( $filename ) = @_;

	printf( STDERR
		"\n" . gettext("Output file %s already exists" ) . " " . gettext(":-/" ) . "\n" .
		"  " . gettext("Svg file not writen! (use -f to force overwriting)" ) . "\n"
	, $filename);

}

# move command in svg path element
#
# param _ - coordinate
# return svg command to move cursor to the specified coordinate
#
sub svg_path_move_to
{
	( $_ ) = @_;

	return( " M $_\n" );
}

# line drawing command in svg path element
#
# param _ - coordinate
# return svg command to draw a line from the current cursor position
#        to the specified coordinate
#
sub svg_path_line_to
{
	( $_ ) = @_;

	return( " L $_\n" );
}

# region drawing end command in svg path element
#
# return svg command to draw a line from the current cursor position
#        to the starting point of the region
#
sub svg_path_close_region
{
	return( " z" );
}

# read a mif-file to memory
#
# param filename - filename of the mif-file to be read
#	return pointer to an array having the content of the file.
# 
sub read_mif_file
{
	my( $filename ) = @_;

	my $mif; # mif file content

	if( ! open( MIF, "$filename" ) )
	{
		&die_mif_file_error( $filename );
	}	

	@$mif = <MIF>;
	close( MIF );

	return( $mif );

}

# read a mid-file to memory
#
# param filename - filename of the mid-file to be read
#	return pointer to an array having the content of the file.
# 
sub read_mid_file
{
	my( $filename ) = @_;
	
	my $mid; # mid file content

	if( ! open( MID, "$filename" ) )
	{
		&print_mid_file_error( $filename );
		@$mid = ();
	}
	else
	{
		@$mid = <MID>;
		close( MID );
	}
	return( $mid );
}	

# write succesfully created svg data to an svg-file 
#
# param filename - filename of the target svg-file
# param svg_data - svg data to be writen
#	return pointer to an array having the content of the file.
# 
sub write_svg_file
{
	my( $filename , $svg_data ) = @_;

	if( -e $filename && ! $options{f} )
	{
		&print_out_file_exists_error( $filename );
	}
	else
	{

		if( ! open( SVG, ">$filename" ) )
		{
			&die_svg_file_error( $filename );
		}

		print( SVG $svg_data );

		close( SVG );
	}

}

# splits mid-file to fields
#
# param mid       - content of a mid-file
# param delimiter - field delimiter defined in mif-file used in mid-file
# return a pointer to an array having pointers to field arrays
#
sub mid_split
{
	my($mid,$delimiter) = @_;

	my $split_mid = []; # pointer to an array for storing row array pointers.
	my $row = [];       # pointer to an array having fields of current row
	my $field = "";     # current field

	foreach( @$mid )
	{
		while( 1 )
		{
			if( /\G([^$delimiter"]+)/gc ) #unquoted
			{
				$field .= $1;
			}
			elsif( /\G"(([^"]|"")*)"/gc ) #quoted
			{
				$field .= $1;
			}
			elsif( /\G${delimiter}/gc ) #delimiter
			{
				$field =~ s/\n$//;
				push( @$row , $field );
				$field = "";				
			}
			elsif( /\G\z/gc ) #row end
			{
				$field =~ s/\n$//;
				push( @$row , $field );
				push( @$split_mid , $row );
				$row = [];
				last
			}
			else #problem
			{
				&print_debug_split( $_ );
				last
			}
		}
		$field = "";				
	}
	return( $split_mid );
}

# xmlify character encoding declaration
#
# param _ - mif character encoding declaration string
# return xml compatible charset encoding declaration
# 
sub mif_charset
{
	( $_ ) = @_;

	s/charset "(.*)"[^"]*$/$1/i;

	# XML specification recommends that labels of character
	# sets, which aren't registered with IANA, should
	# start by "x-". All MapInfo character set declarations
	# (that I'm aware of) are internal, so we simply make
	# sure the declarations start with "x-". 

	if( /^x-/ )
	{
		return( $_ );
	}

	return( "x-$_" );
}

# get delimiter from mif declaration
#
# param _ - mif delimiter declaration string
# return delimiter
# 
sub mif_delimiter
{
	( $_ ) = @_;

	/delimiter "(.)"[^"]*$/i;

	return( $1 );
}

# get mif version from mif declaration
#
# param _ - mif version declaration string
# return mif version number
# 
sub mif_version
{
	( $_ ) = @_;

	return( "unknown" );
}

# get number of column declarations from mif column number declaration
# 
# param - mif column count declaration string
# return number of columns in mid-file
# 
sub mif_column_count
{
	( $_ ) = @_;
	
	/^columns\s*([^\s]*)\s*.*\n$/i;
	
	return( $1 );
}

# get column name from column declaration
#
# param _ - mif column declaration 
# return column name
# 
sub mid_column_name
{
	( $_ ) = @_;
	
	/^\s*([^\s]*)\s*.*\n$/;
	
	return( $1 );
}

# get number of sections of a region. 
# 
# (a region can be a sum of multiple subregions)
#
# param _ - mif region declaration string
# return number of sections
# 
sub mif_region_section_count
{
	( $_ ) = @_;
	
	/^\s*region\s*([^\s]*)\s*.*\n$/i;
	
	return( $1 );
}

# get number of sections of a pline. 
# 
# (a pline can be a sum of multiple subplines)
#
# param _ - mif pline declaration string
# return number of sections
# 
sub mif_pline_section_count
{
	( $_ ) = @_;

	/^\s*pline\s*multiple\s*([^\s]*)\s*.*\n$/i;
	
	return( $1 );
}

# create svg presentation for a region
#
# param coordinates - pointer to an svg compatible coordinate array
# param class_names - mid string with data corresponding to the mif region
# return svg path presentation of the region
# 
sub svg_region
{
	my( $coordinates , $class_names ) = @_;

	my $svg_path_d;     # d attribute for the path element
	my $svg_path_class; # class attribute for the path element
	my $subregion;      # pointer to the array with subregion coordinates
	my $first;          # true when dealing with first sub region
	
	foreach $subregion ( @$coordinates )  #create path element d
	{
		$first = 1;
		foreach( @$subregion )
		{
			if( $first )
			{
				$first = 0;
				$svg_path_d .= &svg_path_move_to( $_ );
			}
			else
			{
				$svg_path_d .= &svg_path_line_to( $_ );
			}
		}
	}
	
	$svg_path_d .= &svg_path_close_region( $class_names );

	$svg_path_class = "mi-region ";
	
	if( defined $class_names)
	{
		$svg_path_class .= $class_names;
	}
	
	return( "\t<path\n\tclass=\"$svg_path_class\"\n\td=\"\n$svg_path_d\" />");
}

# create svg presentation for a pline
#
# param coordinates - pointer to an svg compatible coordinate array
# param class_names - mid string with data corresponding to the mif pline
# return svg path presentation of the pline
# 
sub svg_pline
{
	my($coordinates,$class_names) = @_;

	my $svg_path_d = ""; # d attribute for the path element 
	my $svg_path_class;  # class attribute for the path element 
	my $subline;         # pointer to the array with subpline coordinates 
	my $first;           # true when dealing with first subpline

	foreach $subline ( @$coordinates )
	{
		$first = 1;
		foreach( @$subline )
		{
			if( $first )
			{
				$first = 0;
				$svg_path_d .= &svg_path_move_to( $_ );
			}
			else
			{
				$svg_path_d .= &svg_path_line_to( $_ );
			}
		}
	}

	$svg_path_class = "mi-pline ";
	
	if( defined $class_names)
	{
		$svg_path_class .= $class_names;
	}
	
	return( "\t<path\n\tclass=\"$svg_path_class\"\n\td=\"\n$svg_path_d\" />");
}

# create svg presentation for a line
#
# param line_start  - line starting coordinate
# param line_end    - line ending coordinate
# param class_names - mid string with data corresponding to the mif line
# return svg path presentation of the line
# 
sub svg_line
{
	my( $line_start , $line_end , $class_names ) = @_;

	my $svg_path_d;     # d attribute for the path element 
	my $svg_path_class; # class attribute for the path element
	
	#The MIF specification did not specify the coordinate markup
	#The following is based on a lucky(?) guess ;-)

	$svg_path_d .= &svg_path_move_to( $line_start );
	$svg_path_d .= &svg_path_line_to( $line_end );
	
	$svg_path_class = "mi-line ";
	
	if( defined $class_names)
	{
		$svg_path_class .= $class_names;
	}
	
	
	return( "\t<path\n\tclass=\"$svg_path_class\"\n\td=\"\n$svg_path_d\" />");
}

# convert mif coordinate declaration to an svg coordinate declaration
#
# param mif_coordinate_pair - mif coordinate declaration string
# param minx                - pointer to tiniest x coordinate value until now
#                             in current svg
# param maxx                - pointer to largest x coordinate value until now
#                             in current svg
# param miny                - pointer to tiniest y coordinate value until now
#                             in current svg
# param maxy                - pointer to largest y coordinate value until now
#                             in current svg
# return svg coordinate declaration
#
# if the min/max values change they are written to the scalars
# where the pointers point to.
#  
sub svg_coordinate
{
	my( $mif_coordinate_pair , $minx , $maxx , $miny , $maxy ) = @_;

	#The MIF specification did not specify the coordinate markup
	#The following is based on a lucky(?) guess ;-)
	$mif_coordinate_pair =~ /((-|)[0-9]+(.[0-9]+|)) ((-|)[0-9]+(.[0-9]+|))/;
	
	if(  ! defined $$minx || $1 < $$minx )
	{
		$$minx = $1;
	}
	if( ! defined $$maxx || $1 > $$maxx )
	{
		$$maxx = $1;
	}
	if( ! defined $$miny || $4 < $$miny )
	{
		$$miny = $4;
	}
	if( ! defined $$maxy || $4 > $$maxy )
	{
		$$maxy = $4;
	}		
	
	return( "$1 $4" );
}

# count the coordinates of a multi pline or region section
#
# param _ - mif multi pline or region section coordinate count string
# return number of coordinates
#
sub mif_coordinate_count
{
	( $_ ) = @_;
	
	/^\s*([^\s]*)\s*\n$/;
	
	return( $1 );
}


# count the coordinates of a single pline
#
# param _ - mif pline section coordinate count string
# return number of coordinates
#
sub mif_single_pline_coordinate_count
{
	( $_ ) = @_;
	
	/^\s*pline\s*([^\s]*)\s*\n$/i;
	
	return( $1 );
}

# create svg viewbox declaration
#
# param minx - pointer to tiniest x coordinate value until now in current svg
# param maxx - pointer to largest x coordinate value until now in current svg
# param miny - pointer to tiniest y coordinate value until now in current svg
# param maxy - pointer to largest y coordinate value until now in current svg
# return svg viewbox declaration
#
sub svg_viewbox
{
	my( $minx , $maxx , $miny , $maxy ) = @_;

	return( "$minx -$maxy " . abs( $maxx - $minx ) . " " . abs( $maxy - $miny ) );
}

# create xml header for the svg file
#
# param charset      - xml character encoding declaration
# param view_box     - svg viewbox declaration
# param svg_path_tag - pointer to an array of svg path tags
#	return svg file content
#
sub	xml_headerize
{
	my( $charset , $view_box , $svg_path_tag ) = @_;

	#these should be dehardcoded when needed
	
	my @start =
	(
		"<?xml version=\"1.0\" encoding=\"$charset\" standalone=\"no\"?>\n",
		"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
		"\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
		"<svg xmlns=\"http://www.w3.org/2000/svg\"\n",
		"     xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n",
		"     viewBox=\"$view_box\"\n",
		"     preserveAspectRatio=\"xMinYMin\">\n",
		"\n",
		"	 <style type=\"text/css\" media=\"screen\" title=\"mi2svg\">\n",
		"    .mi-pline { fill: none; }\n",
		"  </style>\n",
		"\n",
		"  <g id=\"v_flip\" transform=\"scale(1, -1)\">\n"
	);

	my @end =
	(
		"\n  </g>\n",
		"</svg>\n"
	);

	return( "@start @$svg_path_tag @end" );
}

# create class names from mid-file data
#
# param mid             - mid-file content
# param delimiter       - mid field delimiter character
# param filename        - filename declaration without filename suffix
# param mid_column_name - pointer to an array having mid column names
# return a pointer to an array of class name strings
# 
sub create_class_names
{
	my( $mid , $delimiter , $filename , $mid_column_name ) = @_;

	# mid file content fields separated
	my $split_mid = &mid_split( $mid , $delimiter );
	
	my $svg_path_classes; # pointer to the class array
	my $svg_path_class;   # class currently under construction

	$filename =~ s/^.*\/([^\/]*)/$1/; #remove path from filename
		
	my $iterator; # iterates trought the mid fields
	
	my $temp_mid_column_name; # duplicate table to "shift"
	                          # Iteration could be used instead.
	
	foreach $iterator ( @$split_mid )
	{

		$svg_path_class = "mi-$filename";
		
		@$temp_mid_column_name = @$mid_column_name;
			
		foreach( @$iterator )
		{
			$svg_path_class .= " mi-$filename-" . shift( @$temp_mid_column_name ) . "-$_";
		}

		push( @$svg_path_classes , $svg_path_class );
	}

	return( $svg_path_classes );
}

# create svg-file data of mif- and mid-file data
#
# param $mif - pointer to an array with the content of mif-file
# param $mid - pointer to an array with the content of mid-file
# return svg-file content
#
sub create_svg
{
	my( $filename ) = @_;

	my $mif = &read_mif_file( "$filename.mif" ); # mif-file content
	my $mid = &read_mid_file( "$filename.mid" ); # mid-file content
	my $svg_path_class; # pointer to an array with class names

	my $mif_version = "unknown"; # version number of the mif processed
	my $xml_charset = "";        # xml form character encoding declaration
	my $delimiter = "\t";        # delmiter character used in mid-file

	my $input_mode = "init";     # current mode of the auto

	# modes:
	#   init     - any understandable content hasn't yet been read
	#   column   - within column declarations
	#   predata  - column declarations have ended, but not yet in data mode
	#   data     - reading map data
	#   pline    - within a pline declaration
	#   region   - within a region declaration
	
	my $section_counter    = 0;  # sections left of a pline/region
	my $coordinate_counter = 0;  # coordinates left of a section
	my $column_counter     = 0;  # column declarations left in column mode

	my $mid_column_name;         # pointer to mid column name array
	my $svg_path_tag;            # pointer to array of ready svg path tags
	my $svg_coordinates;         # pointer to an array of svg coordinate
	                             # array pointers
	my $svg_coordinate;          # pointer to an array of svg coordinates
	
	my $minx; # pointer to tiniest x coordinate value until now in current svg
	my $maxx; # pointer to largest x coordinate value until now in current svg
	my $miny; # pointer to tiniest y coordinate value until now in current svg
	my $maxy; # pointer to largest y coordinate value until now in current svg
	my $svg_viewbox; # svg viewbox declaration
	
	foreach( @$mif )
	{
		if( $input_mode eq "data" )
		{

			if( /^NONE/i )
			{
				shift( @$svg_path_class );
				&print_debug_skip( $input_mode, $_ );
			}
			elsif( /^\s*point/i ) 
			{
				#push( @$svg_path_tag , &svg_point( $_ ) );
			}
			elsif( /^\s*line/i ) 
			{
				/^\s*Line ((-|)[0-9]+(.[0-9]+|) (-|)[0-9]+(.[0-9]+|)) ((-|)[0-9]+(.[0-9]+|) (-|)[0-9]+(.[0-9]+|))/;
			
				push( @$svg_path_tag , &svg_line( &svg_coordinate( $1 ) , &svg_coordinate( $6 ) , shift( @$svg_path_class ) ) );
			}
			elsif( /^\s*pline/i )
			{
				@$svg_coordinates = ();
				@$svg_coordinate = ();

				if( /multiple/i )
				{
					$section_counter = &mif_pline_section_count( $_ );
					$coordinate_counter = 0;
					$input_mode = "psection";
				}
				else
				{
					$section_counter = 0;
					$coordinate_counter = &mif_single_pline_coordinate_count( $_ );
					$input_mode = "pline";
				}

			}
			elsif( /^region/i )
			{
				$section_counter = &mif_region_section_count( $_ );
				$coordinate_counter = 0;
				$input_mode = "rsection";
				@$svg_coordinates = ();
				@$svg_coordinate = ();
			}
			elsif( /^arc/i )
			{
				shift( @$svg_path_class );
				&print_debug_skip( $input_mode, $_ );
			}
			elsif( /^text/i )
			{
				shift( @$svg_path_class );
				&print_debug_skip( $input_mode, $_ );
			}
			elsif( /^rectangle/i )
			{
				shift( @$svg_path_class );
				&print_debug_skip( $input_mode, $_ );
			}
			elsif( /^rounded rectangle/i )
			{
				shift( @$svg_path_class );
				&print_debug_skip( $input_mode, $_ );
			}
			elsif( /^ellipse/i )
			{
				shift( @$svg_path_class );
				&print_debug_skip( $input_mode, $_ );
			}
			else
			{
				&print_debug_skip( $input_mode, $_ );
			}
		}
		elsif( $input_mode eq "region" )
		{
			push( @$svg_coordinate , &svg_coordinate( $_ , \$minx , \$maxx , \$miny , \$maxy ) );
			$coordinate_counter--;

			if( $coordinate_counter == 0)
			{
				push( @$svg_coordinates, $svg_coordinate );
				$svg_coordinate = [];


				if( $section_counter == 0 )
				{
				
					push(	@$svg_path_tag ,	&svg_region
						(
							$svg_coordinates,
							shift( @$svg_path_class )
						)
					);
					$input_mode = "data";
				}
				else
				{
					$input_mode = "rsection";
				}
			}
		}
		elsif( $input_mode eq "rsection" )
		{
			$coordinate_counter = &mif_coordinate_count( $_ );
			$section_counter--;
			$input_mode = "region";
		}
		elsif( $input_mode eq "pline" )
		{
			push( @$svg_coordinate , &svg_coordinate( $_ , \$minx , \$maxx , \$miny , \$maxy ) );
			$coordinate_counter--;

			if( $coordinate_counter == 0)
			{
				push( @$svg_coordinates, $svg_coordinate );
				$svg_coordinate = [];

				if( $section_counter == 0 )
				{
					push( @$svg_path_tag , &svg_pline
						(
							$svg_coordinates,
							shift( @$svg_path_class )
						)
					);
					$input_mode = "data";
				}
				else
				{
					$input_mode = "psection";
				}
			}
		}
		elsif( $input_mode eq "psection" )
		{
			$coordinate_counter = &mif_coordinate_count( $_ );
			$section_counter--;
			$input_mode = "pline";
		}
		elsif( $input_mode eq "column" )		
		{
			push( @$mid_column_name , &mid_column_name( $_ ) );
			$column_counter--;

			if( $column_counter < 1 )
			{
				$svg_path_class = &create_class_names
				(
					$mid,
					$delimiter,
					$filename,
					$mid_column_name
				);

				$input_mode = "predata";
			}
		}	
		else
		{

			if( /^version/i )
			{
				$mif_version = &mif_version( $_ );
			}
			elsif( /^charset/i )
			{
				$xml_charset = &mif_charset( $_ );
			}
			elsif( /^delimiter/i )
			{
				$delimiter = &mif_delimiter( $_ );
			}
			elsif( /^columns/i )
			{
				$column_counter = &mif_column_count( $_ );
				if( $column_counter > 0 )
				{
					$input_mode = "column";
				}
				else
				{
					$input_mode = "predata";
				}
			}
			elsif( /^data/i )
			{
				$input_mode = "data";
			}
			else
			{
				&print_debug_skip( $input_mode, $_ );
			}
		}
	}
	
	if( ! defined $minx || ! defined $maxx || ! defined $miny || ! defined $maxy )
	{
		&die_no_objects_error( $filename )
	}
	
	$svg_viewbox = &svg_viewbox( $minx , $maxx , $miny , $maxy );
		
	return( &xml_headerize( $xml_charset , $svg_viewbox , $svg_path_tag ) );
}

my $filename; #filename of currently prosessed file

foreach $filename ( @ARGV )
{
	if(! -e "$filename.mif" )
	{
		$filename =~ s/.mif$//;
	}
	
	eval
	{
		&write_svg_file( "$filename.svg" , &create_svg( $filename ) );
	};
}

if( $#ARGV < 0)
{
	&print_banner( );
	&print_usage( );
}

