#
# Highway drawing functions
#

use warnings;
use strict;

sub CreateLineRules
  {
   my($global,$data)=(@_);

   my($n,$m);

   # Check the data

   foreach $n (0..$#{$data})
     {
      warn_incompatible_zoom("Line","CASING"       ,$data->[$n]) if($data->[$n]{'MIN-ZOOM-CASING'}       <$global->{MAXZOOM});
      warn_incompatible_zoom("Line","TUNNEL-BRIDGE",$data->[$n]) if($data->[$n]{'MIN-ZOOM-TUNNEL-BRIDGE'}<$global->{MAXZOOM});
      warn_incompatible_zoom("Line","ONEWAY"       ,$data->[$n]) if($data->[$n]{'MIN-ZOOM-ONEWAY'}       <$global->{MAXZOOM});
      warn_incompatible_zoom("Line","LABEL"        ,$data->[$n]) if($data->[$n]{'MIN-ZOOM-LABEL'}        <$global->{MAXZOOM});
      warn_incompatible_zoom("Line","LABEL2"       ,$data->[$n]) if($data->[$n]{'MIN-ZOOM-LABEL2'}       <$global->{MAXZOOM});

      warn_missing_information2("Line","CASING","CASING-COLOUR",$data->[$n]);

      warn_missing_information2("Line","TUNNEL-BRIDGE","TUNNEL-FILL-COLOUR"  ,$data->[$n],1);
      warn_missing_information2("Line","TUNNEL-BRIDGE","TUNNEL-CASING-COLOUR",$data->[$n],1);
      warn_missing_information2("Line","TUNNEL-BRIDGE","BRIDGE-CASING-COLOUR",$data->[$n],1);

      warn_missing_information2("Line","LABEL","LABEL-COLOUR",$data->[$n]);
      warn_missing_information2("Line","LABEL","LABEL-SIZE"  ,$data->[$n]);
      warn_missing_information2("Line","LABEL","LABEL"       ,$data->[$n]);

      warn_missing_information2("Line","LABEL2","LABEL2-COLOUR",$data->[$n]);
      warn_missing_information2("Line","LABEL2","LABEL2-SIZE"  ,$data->[$n]);
      warn_missing_information2("Line","LABEL2","LABEL2"       ,$data->[$n]);

      foreach $m ($n+1..$#{$data})
        {
         next if($data->[$n]{LAYER} ne $data->[$m]{LAYER});
         next if($data->[$n]{STYLE} ne $data->[$m]{STYLE});
         next if($data->[$n]{FILTER} ne $data->[$m]{FILTER} || $data->[$n]{'SUB-FILTER'} ne $data->[$m]{'SUB-FILTER'});

         warn_overlapping_lines("Line","",$data->[$n],$data->[$m]);
        }
     }

   # Create the layers, styles and rules

   my($zoom,$datum);

   foreach $zoom ($global->{MINZOOM}..$global->{MAXZOOM})
     {
      # Create the layers

      foreach $datum (@{$data})
        {
         add_layer($global,
                   name=>"lines--$datum->{LAYER}--z$zoom",
                   description=>"lines $datum->{LAYER}",
                   zoom=>$zoom,
                   'datasource-base'=>'postgis',
                   'sql-table'=>'planet_osm_line',
                   'extra-sql-column-clause'=>"CASE WHEN layer IS null THEN 0::integer WHEN layer IN ('-5','-4','-3','-2','-1','0','1','2','3','4','5') THEN int4(layer) ELSE 0::integer END AS z",
                   'extra-sql-order-clause'=>'z',
                   'group-by'=>'z');
        }

      # Create the shield styles

      foreach $datum (@{$data})
        {
         next if($zoom < $datum->{'MIN-ZOOM'} ||
                 $zoom > $datum->{'MAX-ZOOM'});

         next if($zoom < $datum->{'MIN-ZOOM-LABEL'});

         next if($datum->{'SHIELD-SYMBOL'} eq "");

         # Select the existing layer

         add_layer($global,name=>"lines--$datum->{LAYER}--z$zoom");

         # Create the style (may re-use previous one if names match)

         add_style($global,
                   name=>"lines--$datum->{LAYER}--$datum->{STYLE}--shield-z$zoom",
                   zoom=>$zoom);

         # Create the rules

         my($filter)="($datum->{FILTER})";

         if($datum->{'SUB-FILTER'} ne "")
           {
            $filter.=" and ($datum->{'SUB-FILTER'})";
           }

         $datum->{'LABEL'} =~ m%\[([^]]+)\]%;
         my($what)=$1;

         my($shield8)=$datum->{'SHIELD-SYMBOL'};
         $shield8 =~ s%\[length\]%8%;

         add_rule($global,
                  zoom=>$zoom,
                  filter=>"$filter and ([${what}_length]=9)",
                  symbolisers=>[shield_symboliser($datum->{'LABEL-STYLE'},
                                                  $datum->{'LABEL'},
                                                  'file'=>$shield8,
                                                  'placement'=>'line',
                                                  'spacing'=>256,
                                                  'minimum-distance'=>128,
                                                  'clip'=>'false',
                                                  'fill'=>$datum->{'LABEL-COLOUR'},
                                                  'size'=>$datum->{'LABEL-SIZE'},
                                                  'fontset-name'=>'normal')]);

         my($shield7)=$datum->{'SHIELD-SYMBOL'};
         $shield7 =~ s%\[length\]%7%;

         add_rule($global,
                  zoom=>$zoom,
                  filter=>"$filter and ([${what}_length]=8)",
                  symbolisers=>[shield_symboliser($datum->{'LABEL-STYLE'},
                                                  $datum->{'LABEL'},
                                                  'file'=>$shield7,
                                                  'placement'=>'line',
                                                  'spacing'=>256,
                                                  'minimum-distance'=>128,
                                                  'clip'=>'false',
                                                  'fill'=>$datum->{'LABEL-COLOUR'},
                                                  'size'=>$datum->{'LABEL-SIZE'},
                                                  'fontset-name'=>'normal')]);

         my($shield6)=$datum->{'SHIELD-SYMBOL'};
         $shield6 =~ s%\[length\]%6%;

         add_rule($global,
                  zoom=>$zoom,
                  filter=>"$filter and ([${what}_length]=7)",
                  symbolisers=>[shield_symboliser($datum->{'LABEL-STYLE'},
                                                  $datum->{'LABEL'},
                                                  'file'=>$shield6,
                                                  'placement'=>'line',
                                                  'spacing'=>256,
                                                  'minimum-distance'=>128,
                                                  'clip'=>'false',
                                                  'fill'=>$datum->{'LABEL-COLOUR'},
                                                  'size'=>$datum->{'LABEL-SIZE'},
                                                  'fontset-name'=>'normal')]);

         my($shield)=$datum->{'SHIELD-SYMBOL'};
         $shield =~ s%\[length\]%[${what}_length]%;

         add_rule($global,
                  zoom=>$zoom,
                  filter=>"$filter and ([${what}_length]&gt;0 and [${what}_length]&lt;=6)",
                  symbolisers=>[shield_symboliser($datum->{'LABEL-STYLE'},
                                                  $datum->{'LABEL'},
                                                  'file'=>$shield,
                                                  'placement'=>'line',
                                                  'spacing'=>256,
                                                  'minimum-distance'=>128,
                                                  'clip'=>'false',
                                                  'fill'=>$datum->{'LABEL-COLOUR'},
                                                  'size'=>$datum->{'LABEL-SIZE'},
                                                  'fontset-name'=>'normal')]);
        }

      # Create the label styles

      foreach $datum (@{$data})
        {
         next if($zoom < $datum->{'MIN-ZOOM'} ||
                 $zoom > $datum->{'MAX-ZOOM'});

         next if($zoom < $datum->{'MIN-ZOOM-LABEL'} && $zoom < $datum->{'MIN-ZOOM-LABEL2'});

         next if($datum->{'SHIELD-SYMBOL'} ne "");

         # Select the existing layer

         add_layer($global,name=>"lines--$datum->{LAYER}--z$zoom");

         # Create the style (may re-use previous one if names match)

         add_style($global,
                   name=>"lines--$datum->{LAYER}--$datum->{STYLE}--label-z$zoom",
                   zoom=>$zoom);

         # Create the symbolisers

         my(@symbolisers)=();

         if($zoom >= $datum->{'MIN-ZOOM-LABEL'} &&
            $datum->{'LABEL'} ne "")
           {
            push(@symbolisers,text_symboliser($datum->{'LABEL-STYLE'},
                                              $datum->{'LABEL'},
                                              'placement'=>'line',
                                              'spacing'=>256,
                                              'minimum-distance'=>128,
                                              'clip'=>'false',
                                              'fill'=>$datum->{'LABEL-COLOUR'},
                                              'size'=>$datum->{'LABEL-SIZE'},
                                              'halo-radius'=>1,
                                              'fontset-name'=>'normal'));
           }

         if($zoom >= $datum->{'MIN-ZOOM-LABEL2'} &&
            $datum->{'LABEL2'} ne "")
           {
            push(@symbolisers,text_symboliser($datum->{'LABEL2-STYLE'},
                                              $datum->{'LABEL2'},
                                              'placement'=>'line',
                                              'spacing'=>256,
                                              'minimum-distance'=>128,
                                              'clip'=>'false',
                                              'fill'=>$datum->{'LABEL2-COLOUR'},
                                              'size'=>$datum->{'LABEL2-SIZE'},
                                              'halo-radius'=>1,
                                              'fontset-name'=>'normal'));
           }

         # Create the rules

         my($filter)="($datum->{FILTER})";

         if($datum->{'SUB-FILTER'} ne "")
           {
            $filter.=" and ($datum->{'SUB-FILTER'})";
           }

         add_rule($global,
                  zoom=>$zoom,
                  filter=>$filter,
                  symbolisers=>[@symbolisers]);
        }

      # Create the oneway styles

      foreach $datum (@{$data})
        {
         next if($zoom < $datum->{'MIN-ZOOM'} ||
                 $zoom > $datum->{'MAX-ZOOM'});

         next if($zoom < $datum->{'MIN-ZOOM-ONEWAY'});

         # Select the existing layer

         add_layer($global,name=>"lines--$datum->{LAYER}--z$zoom");

         # Create the style (may re-use previous one if names match)

         add_style($global,
                   name=>"lines--$datum->{LAYER}--$datum->{STYLE}--oneway-z$zoom",
                   zoom=>$zoom);

         # Create the rules

         my($filter)="($datum->{FILTER})";

         if($datum->{'SUB-FILTER'} ne "")
           {
            $filter.=" and ($datum->{'SUB-FILTER'})";
           }

         add_rule($global,
                  zoom=>$zoom,
                  filter=>"$filter and ([oneway]='1')",
                  symbolisers=>[line_pattern_symboliser("",
                                                        'base'=>'symbols',
                                                        'file'=>'arrow.png')]);

         add_rule($global,
                  zoom=>$zoom,
                  filter=>"$filter and ([oneway]='-1')",
                  symbolisers=>[line_pattern_symboliser("",
                                                        'base'=>'symbols',
                                                        'file'=>'arrow_back.png')]);
        }

      # Create the fill styles

      foreach $datum (@{$data})
        {
         next if($zoom < $datum->{'MIN-ZOOM'} ||
                 $zoom > $datum->{'MAX-ZOOM'});

         # Select the existing layer

         add_layer($global,name=>"lines--$datum->{LAYER}--z$zoom");

         # Create the style (may re-use previous one if names match)

         add_style($global,
                   name=>"lines--$datum->{LAYER}--$datum->{STYLE}--fill--z$zoom",
                   zoom=>$zoom);

         # Create the rules

         my(@symbolisers);

         my($filter)="($datum->{FILTER})";

         if($datum->{'SUB-FILTER'} ne "")
           {
            $filter.=" and ($datum->{'SUB-FILTER'})";
           }

         if($zoom >= $datum->{'MIN-ZOOM-TUNNEL-BRIDGE'})
           {
            # A tunnel

            @symbolisers=();

            if($datum->{'UNDERLAY-COLOUR'} ne "")
              {
               push(@symbolisers,line_symboliser("",
                                                 'stroke'=>$datum->{'UNDERLAY-COLOUR'},
                                                 'stroke-linejoin'=>'round',
                                                 'stroke-width'=>$datum->{"WIDTH-Z$zoom"}));
              }

            if($datum->{'FILL-PATTERN'} ne "")
              {
               push(@symbolisers,line_pattern_symboliser($datum->{'FILL-STYLE'},
                                                         'base'=>'symbols',
                                                         'file'=>$datum->{'FILL-PATTERN'}));
              }
            elsif($datum->{'TUNNEL-FILL-COLOUR'} ne "")
              {
               push(@symbolisers,line_symboliser($datum->{'FILL-STYLE'},
                                                 'stroke'=>$datum->{'TUNNEL-FILL-COLOUR'},
                                                 'stroke-linejoin'=>'round',
                                                 'stroke-width'=>$datum->{"WIDTH-Z$zoom"}));
              }
            else
              {
               push(@symbolisers,line_symboliser($datum->{'FILL-STYLE'},
                                                 'stroke'=>$datum->{'FILL-COLOUR'},
                                                 'stroke-linejoin'=>'round',
                                                 'stroke-width'=>$datum->{"WIDTH-Z$zoom"}));
              }

            add_rule($global,
                     zoom=>$zoom,
                     filter=>"$filter and ([tunnel]='yes')",
                     symbolisers=>[@symbolisers]);

            # A bridge (not using a dashed style - rounded linecaps make for a cleaner join)

            if($datum->{'FILL-STYLE'} !~ m%stroke-dasharray%)
              {
               @symbolisers=();

               if($datum->{'UNDERLAY-COLOUR'} ne "")
                 {
                  push(@symbolisers,line_symboliser("",
                                                    'stroke'=>$datum->{'UNDERLAY-COLOUR'},
                                                    'stroke-linejoin'=>'round',
                                                    'stroke-linecap'=>'round',
                                                    'stroke-width'=>$datum->{"WIDTH-Z$zoom"}));
                 }

               if($datum->{'FILL-PATTERN'} ne "")
                 {
                  push(@symbolisers,line_pattern_symboliser($datum->{'FILL-STYLE'},
                                                            'base'=>'symbols',
                                                            'file'=>$datum->{'FILL-PATTERN'}));
                 }
               else
                 {
                  push(@symbolisers,line_symboliser($datum->{'FILL-STYLE'},
                                                    'stroke'=>$datum->{'FILL-COLOUR'},
                                                    'stroke-linejoin'=>'round',
                                                    'stroke-linecap'=>'round',
                                                    'stroke-width'=>$datum->{"WIDTH-Z$zoom"}));
                 }

               add_rule($global,
                        zoom=>$zoom,
                        filter=>"$filter and ([bridge]='yes')",
                        symbolisers=>[@symbolisers]);
              }
           }

         # Not a tunnel or bridge

         @symbolisers=();

         if($datum->{'UNDERLAY-COLOUR'} ne "")
           {
            push(@symbolisers,line_symboliser("",
                                              'stroke'=>$datum->{'UNDERLAY-COLOUR'},
                                              'stroke-linejoin'=>'round',
                                              'stroke-width'=>$datum->{"WIDTH-Z$zoom"}));
           }

         if($datum->{'FILL-PATTERN'} ne "")
           {
            push(@symbolisers,line_pattern_symboliser($datum->{'FILL-STYLE'},
                                                      'base'=>'symbols',
                                                      'file'=>$datum->{'FILL-PATTERN'}));
           }
         elsif($datum->{'FILL-COLOUR'} ne "")
           {
            push(@symbolisers,line_symboliser($datum->{'FILL-STYLE'},
                                              'stroke'=>$datum->{'FILL-COLOUR'},
                                              'stroke-linejoin'=>'round',
                                              'stroke-width'=>$datum->{"WIDTH-Z$zoom"}));
           }

         add_rule($global,
                  zoom=>$zoom,
                  filter=>$filter,
                  symbolisers=>[@symbolisers]);
        }

      # Create the casing styles

      foreach $datum (@{$data})
        {
         next if($zoom < $datum->{'MIN-ZOOM'} ||
                 $zoom > $datum->{'MAX-ZOOM'});

         next if($zoom < $datum->{'MIN-ZOOM-CASING'} &&
                 $zoom < $datum->{'MIN-ZOOM-TUNNEL-BRIDGE'});

         # Select the existing layer

         add_layer($global,name=>"lines--$datum->{LAYER}--z$zoom");

         # Create the style (may re-use previous one if names match)

         add_style($global,
                   name=>"lines--$datum->{LAYER}--$datum->{STYLE}--casing--z$zoom",
                   zoom=>$zoom);

         my($filter)="($datum->{FILTER})";

         if($datum->{'SUB-FILTER'} ne "")
           {
            $filter.=" and ($datum->{'SUB-FILTER'})";
           }

         my($width)=1.5*$datum->{"WIDTH-Z$zoom"};

         if($width-$datum->{"WIDTH-Z$zoom"} > 3)
           {
            $width=$datum->{"WIDTH-Z$zoom"} + 3;
           }
         elsif($width-$datum->{"WIDTH-Z$zoom"} < 1)
           {
            $width=$datum->{"WIDTH-Z$zoom"} + 1;
           }

         if($zoom >= $datum->{'MIN-ZOOM-TUNNEL-BRIDGE'})
           {
            if($datum->{'BRIDGE-CASING-COLOUR'} ne "")
              {
               add_rule($global,
                        zoom=>$zoom,
                        filter=>"$filter and ([bridge]='yes')",
                        symbolisers=>[line_symboliser("",
                                                      'stroke'=>$datum->{'BRIDGE-CASING-COLOUR'},
                                                      'stroke-linejoin'=>'round',
                                                      'stroke-width'=>$width)]);
              }

            if($datum->{'TUNNEL-CASING-COLOUR'} ne "")
              {
               add_rule($global,
                        zoom=>$zoom,
                        filter=>"$filter and ([tunnel]='yes')",
                        symbolisers=>[line_symboliser("",
                                                      'stroke'=>$datum->{'TUNNEL-CASING-COLOUR'},
                                                      'stroke-linejoin'=>'round',
                                                      'stroke-width'=>$width,
                                                      'stroke-dasharray'=>'4,2')]);
              }
           }

         if($zoom >= $datum->{'MIN-ZOOM-CASING'})
           {
            if($datum->{'CASING-COLOUR'} ne "")
              {
               add_rule($global,
                        zoom=>$zoom,
                        filter=>$filter,
                        symbolisers=>[line_symboliser("",
                                                      'stroke'=>$datum->{'CASING-COLOUR'},
                                                      'stroke-linejoin'=>'round',
                                                      'stroke-width'=>$width)]);
              }
           }
        }
     }
  }

#
1;
