#
# Functions for text files
#

use warnings;
use strict;

require "colour-functions.pl";


# Read in a text file and convert it to an array of hashes.

sub ReadText
  {
   my($global,$filename)=(@_);

   my(@datalist)=();

   # Open the file

   open(TXT,"<$filename") || die "Cannot open '$filename'\n";

   # Read the header

   $_=<TXT>;

   s%\r*\n%%;

   my(@columns)=split("\t");

   # Read the remaining lines

   while(<TXT>)
     {
      s%\r*\n%%;

      # Skip comments or blank lines

      if(m%^\t*#% || m%^\t*$%)
        {
         next;
        }

      # Split the line into columns and process them

      my(@cols)=split("\t");

      my(%row)=();
      my($n);

      foreach $n (0..$#columns)
        {
         if($n>$#cols)
           {
            $row{$columns[$n]}="";
            next;
           }

         if($cols[$n] =~ m&^=darken\(([-A-Z]+),([.0-9]+)%\)$&)
           {
            $cols[$n]=darken($row{$1},$2);
           }

         if($cols[$n] =~ m&^=lighten\(([-A-Z]+),([.0-9]+)%\)$&)
           {
            $cols[$n]=lighten($row{$1},$2);
           }

         if($cols[$n] =~ m&^=([-A-Z]+)$&)
           {
            $cols[$n]=$row{$1};
           }

         $row{$columns[$n]}=$cols[$n];
        }

      # Handle min-zoom and max-zoom if left empty

      my($row);

      foreach $row (keys %row)
        {
         if($row =~ m%^MIN-ZOOM(.*)$%)
           {
            if($row{$row} eq "")
              {
               if(defined $row{"MAX-ZOOM$1"})
                 {
                  if($row{"MAX-ZOOM$1"} eq "")
                    {
                     $row{"MIN-ZOOM$1"}=$global->{MAXZOOM}+1; # Never matches
                     $row{"MAX-ZOOM$1"}=$global->{MINZOOM}-1; # Never matches
                    }
                  else
                    {
                     $row{"MIN-ZOOM$1"}=$global->{MINZOOM}; # Always matches
                    }
                 }
               else
                 {
                  $row{"MIN-ZOOM$1"}=$global->{MAXZOOM}+1; # Never matches
                 }
              }
            else
              {
               if(defined $row{"MAX-ZOOM$1"})
                 {
                  if($row{"MAX-ZOOM$1"} eq "")
                    {
                     $row{"MAX-ZOOM$1"}=$global->{MAXZOOM}; # Always matches
                    }
                 }
              }
           }
        }

      # Handle width-z18 if left empty and fill in the other zooms

      if(defined $row{'WIDTH-Z18'})
        {
         if($row{'WIDTH-Z18'} eq "")
           {
            $row{"WIDTH-Z18"}=0;
           }

         my($zoom);

         foreach $zoom ($global->{MINZOOM}..$global->{MAXZOOM})
           {
            next if($zoom==18);

            $row{"WIDTH-Z$zoom"}=sprintf("%.1f",$row{'WIDTH-Z18'}*exp(log(2.0)*($zoom-18)/2.0));
           }
        }

      # Store the data

      push(@datalist,{%row});
     }

   close(TXT);

   return [@datalist];
  }


# Check for overlapping zoom ranges

sub overlapping_zooms
  {
   my($minzoom1,$maxzoom1,$minzoom2,$maxzoom2)=(@_);

   if($minzoom1 > $maxzoom1) { return 0; }
   if($minzoom2 > $maxzoom2) { return 0; }

   if($minzoom1 >= $minzoom2 && $minzoom1 <= $maxzoom2) { return 1; }
   if($maxzoom1 >= $minzoom2 && $maxzoom1 <= $maxzoom2) { return 1; }

   return 0;
  }

# Warn if overlapping zoom ranges in multiple lines for the same object

sub warn_overlapping_lines
  {
   my($type,$suffix,$data1,$data2)=(@_);

   if($suffix ne "")
     {
      $suffix="-".$suffix;
     }

   if(overlapping_zooms($data1->{"MIN-ZOOM".$suffix},$data1->{"MAX-ZOOM".$suffix},$data2->{"MIN-ZOOM".$suffix},$data2->{"MAX-ZOOM".$suffix}))
     {
      print STDERR "Warning: $type layer '$data1->{LAYER}' style '$data1->{STYLE}' has two entries with overlapping zoom ranges (MIN-ZOOM$suffix/MAX-ZOOM$suffix).\n";
     }
  }

# Warn if missing information in a line for an object

sub warn_missing_information
  {
   my($type,$suffix,$info,$data)=(@_);

   if($suffix ne "")
     {
      $suffix="-".$suffix;
     }

   if($data->{"MIN-ZOOM".$suffix}<$data->{"MAX-ZOOM".$suffix} && $data->{$info} eq "")
     {
      print STDERR "Warning: $type layer '$data->{LAYER}' style '$data->{STYLE}' has zoom ranges (MIN-ZOOM$suffix/MAX-ZOOM$suffix) but missing data ($info).\n";
     }

   if($data->{"MIN-ZOOM".$suffix}>$data->{"MAX-ZOOM".$suffix} && $data->{$info} ne "")
     {
      print STDERR "Warning: $type layer '$data->{LAYER}' style '$data->{STYLE}' has data ($info) but no zoom ranges (MIN-ZOOM$suffix/MAX-ZOOM$suffix).\n";
     }
  }

# Warn if missing information in a line for an object (with asymmetric zoom names)

sub warn_missing_information2
  {
   my($type,$suffix,$info,$data,$optional)=(@_);

   if($suffix ne "")
     {
      $suffix="-".$suffix;
     }

   if(!$optional && $data->{"MIN-ZOOM".$suffix}<$data->{"MAX-ZOOM"} && $data->{$info} eq "")
     {
      print STDERR "Warning: $type layer '$data->{LAYER}' style '$data->{STYLE}' has zoom ranges (MIN-ZOOM$suffix/MAX-ZOOM) but missing data ($info).\n";
     }

   if($data->{"MIN-ZOOM".$suffix}>$data->{"MAX-ZOOM"} && $data->{$info} ne "")
     {
      print STDERR "Warning: $type layer '$data->{LAYER}' style '$data->{STYLE}' has data ($info) but no zoom ranges (MIN-ZOOM$suffix/MAX-ZOOM).\n";
     }
  }

# Warn if information in a line for an object has incompatible zoom ranges

sub warn_incompatible_zoom
  {
   my($type,$suffix,$data)=(@_);

   if($suffix ne "")
     {
      $suffix="-".$suffix;
     }

   if($data->{'MIN-ZOOM'}>$data->{"MIN-ZOOM".$suffix} || $data->{"MIN-ZOOM".$suffix}>$data->{'MAX-ZOOM'})
     {
      print STDERR "Warning: $type layer '$data->{LAYER}' style '$data->{STYLE}' has incompatible zoom (MIN-ZOOM$suffix) with overall zoom ranges (MIN-ZOOM/MAX-ZOOM).\n";
     }
  }

#
1;
