#
# Functions for symbolisers.
#

use warnings;
use strict;

# Allowed styles

my(%allowed_polygon_pattern_styles)=(
                                     'base'=>'.+',
                                     'file'=>'.+'
                                    );

my(%allowed_polygon_styles)=(
                             'fill'=>'.+',
                             'fill-opacity'=>'[0-9.]+',
                             'gamma'=>'[0-9.]+'
                            );

my(%allowed_line_pattern_styles)=(
                                  'base'=>'.+',
                                  'file'=>'.+'
                                 );

my(%allowed_line_styles)=(
                          'stroke'=>'.+',
                          'stroke-width'=>'[0-9.]+',
                          'stroke-opacity'=>'[0-9.]+',
                          'stroke-linejoin'=>'(miter|round|bevel)',
                          'stroke-linecap'=>'(round|butt|square)',
                          'stroke-dasharray'=>'[0-9]+,[0-9]+(,[0-9]+)*'
                         );

my(%allowed_point_styles)=(
                           'base'=>'.+',
                           'file'=>'.+',
                           'allow-overlap'=>'(true|false)',
                           'opacity'=>'[0-9.]+',
                           'transform'=>'.+',
                           'ignore-placement'=>'(true|false)'
                          );

my(%allowed_text_styles)=(
                          'text-ratio'=>'[0-9.]+',
                          'wrap-width'=>'[0-9.]+',
                          'wrap-before'=>'(true|false)',
                          'spacing'=>'[0-9.]+',
                          'label-position-tolerance'=>'[0-9.]+',
                          'force-odd-labels'=>'(true|false)',
                          'max-char-angle-delta'=>'[0-9.]+',
                          'halo-rasterizer'=>'(fast|full)',
                          'dx'=>'-?[0-9.]+',
                          'dy'=>'-?[0-9.]+',
                          'avoid-edges'=>'(true|false)',
                          'minimum-distance'=>'[0-9.]+',
                          'allow-overlap'=>'(true|false)',
                          'placement'=>'(line|point|vertex|interior)',
                          'vertical-alignment'=>'(top|middle|bottom|auto)',
                          'horizontal-alignment'=>'(left|middle|right|auto)',
                          'justify-alignment'=>'(left|middle|right|auto)',
                          'opacity'=>'[0-9.]+',
                          'minimum-padding'=>'[0-9.]+',
                          'minimum-path-length'=>'[0-9.]+',
                          'orientation'=>'[0-9.]+',
                          'rotate-displacement'=>'(true|false)',
                          'placement-type'=>'(dummy|simple|list)',
                          'placements'=>'.+',
                          'upright'=>'(left|right|auto|left_only|right_only)',
                          'clip'=>'(true|false)',
                          'largest_bbox_only'=>'(true|false)',

                          'face-name'=>'.+',
                          'fontset-name'=>'.+',
                          'size'=>'[0-9.]+',
                          'fill'=>'.+',
                          'halo-fill'=>'.+',
                          'halo-radius'=>'[0-9.]+',
                          'character-spacing'=>'[0-9.]+',
                          'line-spacing'=>'[0-9.]+',
                          'wrap-character'=>'.',
                          'text-transform'=>'(none|uppercase|lowercase|capitalize)'
                         );

my(%allowed_shield_styles)=(
                            'base'=>'.+',
                            'file'=>'.+',
                            'opacity'=>'[0-9.]+',
                            'text-opacity'=>'[0-9.]+',
                            'shield-dx'=>'-?[0-9.]+',
                            'shield-dy'=>'-?[0-9.]+',
                            'transform'=>'.+'
                           );


# Split a symboliser style

sub split_symboliser_style
  {
   my($parameters,$styles)=(@_);

   if($styles ne "")
     {
      my(@styles)=split(" *; *",$styles);

      my($style);

      foreach $style (@styles)
        {
         my($key,$value)=split(" *= *",$style);
         $value =~ s%^"(.*)"$%$1%;
         $value =~ s%^'(.*)'$%$1%;

         $parameters->{$key}=$value;
        }
     }
  }

# Check for valid symboliser styles

sub check_styles
  {
   my($type,$parameters,%allowed)=(@_);

   my($parameter);

   foreach $parameter (keys %$parameters)
     {
      if(!defined $allowed{$parameter})
        {
         print Dumper($parameters);

         die "Invalid style parameter '$parameter' for $type symboliser.\n";
        }

      my($value)=$parameters->{$parameter};

      if($value !~ m%^$allowed{$parameter}$%)
        {
         print Dumper($parameters);

         die "Invalid style parameter value '$value' for parameter '$parameter' of $type symboliser.\n";
        }
     }
  }

# Create a polygon symboliser

sub polygon_pattern_symboliser
  {
   my($styles,%parameters)=(@_);

   split_symboliser_style(\%parameters,$styles);

   check_styles('PolygonPatternSymbolizer',\%parameters,%allowed_polygon_pattern_styles);

   return {name=>'PolygonPatternSymbolizer',parameters=>{%parameters}};
  }

# Create a polygon symboliser

sub polygon_symboliser
  {
   my($styles,%parameters)=(@_);

   split_symboliser_style(\%parameters,$styles);

   check_styles('PolygonSymbolizer',\%parameters,%allowed_polygon_styles);

   return {name=>'PolygonSymbolizer',parameters=>{%parameters}};
  }

# Create a line pattern symboliser

sub line_pattern_symboliser
  {
   my($styles,%parameters)=(@_);

   split_symboliser_style(\%parameters,$styles);

   check_styles('LinePatternSymbolizer',\%parameters,%allowed_line_pattern_styles);

   return {name=>'LinePatternSymbolizer',parameters=>{%parameters}};
  }

# Create a line symboliser

sub line_symboliser
  {
   my($styles,%parameters)=(@_);

   split_symboliser_style(\%parameters,$styles);

   check_styles('LineSymbolizer',\%parameters,%allowed_line_styles);

   return {name=>'LineSymbolizer',parameters=>{%parameters}};
  }

# Create a point symboliser

sub point_symboliser
  {
   my($styles,%parameters)=(@_);

   split_symboliser_style(\%parameters,$styles);

   check_styles('PointSymbolizer',\%parameters,%allowed_point_styles);

   return {name=>'PointSymbolizer',parameters=>{%parameters}};
  }

# Create a text symboliser

sub text_symboliser
  {
   my($styles,$text,%parameters)=(@_);

   split_symboliser_style(\%parameters,$styles);

   check_styles('TextSymbolizer',\%parameters,%allowed_text_styles);

   return {name=>'TextSymbolizer',content=>$text,parameters=>{%parameters}};
  }

# Create a shield symboliser

sub shield_symboliser
  {
   my($styles,$text,%parameters)=(@_);

   split_symboliser_style(\%parameters,$styles);

   check_styles('ShieldSymbolizer',\%parameters,%allowed_text_styles,%allowed_shield_styles);

   return {name=>'ShieldSymbolizer',content=>$text,parameters=>{%parameters}};
  }

#
1;
