package ACIS::Web::Config;

use XML::XPath;
use strict;

use ACIS::Web::Config::Screen;
use ACIS::LocalConfig;
use ACIS::Common;

use CGI;

use AppConfig;

sub retrieve {
  my $class = shift;
  my $data_dir = shift;
  my $config_file = shift;
  my $screen_file = shift;
  
  #my $data_dir =~ s/\/$//);
  
  my $self =  {
    'home'    => $data_dir,
    'file'    => $config_file,
    'screen-config' => $screen_file,
    'screens' => {},
    'modules' => [],
   };
   
  bless $self, $class;
  
  $self -> load;
  
  $self -> load_screens;
  
  $self -> check;
  
  return $self;
}


sub load {
  my $self = shift;
  
  my $parameters = {
    # global parameters
    'site-name',        'required',
    'site-name-long',   'required',
    'admin-email',      'required',
#    'home',             'required',  # not required for ACIS-Web
    'log-verbosity',    'not-defined',
#    'encoding',         'not-defined', # not needed
    
    
    # web interface
    'base-url',         'required',
    'static-base-url',  'required',
    'static-base-dir',  'required',
    'template-set',     'default',
    'css-url',          'not-defined',
    'session-lifetime', '15',
    'problem-report-url', 'not-defined',
    
    # email-related
    'system-email',     'required',
    'institutions-maintainer-email', 'required',
    'sendmail',         'required',
    
    # The data that ACIS produces
#   'output-data-redif', 'not-defined',
#   'output-data-amf',   'not-defined'
    'person-id-prefix', 'required',
    
    # database parameters
    'metadata-db-name', 'required',
    'db-name',          'required',
    'db-user',          'required',
    'db-pass',          'required',
    'db-port',          'not-defined',
    'db-site',          'not-defined',

   };
  
  my $data_dir = $self -> {'home'};
  
  # create a new AppConfig object
  
  my $filename = $self -> {'file'};
  my $config = new AppConfig ( {GLOBAL => {ARGCOUNT => 1}}, keys %$parameters );
  
  $config -> file ( $filename );

  # go through the parameters, requesting the values from the file and storing
  # them into $self hash
  
  foreach ( keys %$parameters ) {

    my $value = $config -> get ($_);
    
    if ( $parameters -> {$_} eq 'required' ) {
      critical "required configuration parameter '$_' is absent"
       unless defined $value and $value;

      $self -> {"$_"} = $value;

    } elsif ( $parameters -> {$_} eq 'not-defined' ) {
      $self -> {$_} = $value
       if defined $value and $value;

    } else {
      if ( defined $value ) {
        $self -> {$_} = $value;
	
      } else {
        $self -> {$_} = $parameters -> {$_};
      } 
    }
      
    
  }
}


sub screen {
  my $self = shift;
  my $screen_name = shift;
  
  return $self -> {'screens'} -> {$screen_name};
}


sub load_screens {
  my $self = shift;
  
  my $screen_config_path = $self -> {'screen-config'};
  
  debug 'loading screens configuration';
  
  my $xp = new XML::XPath (filename => $screen_config_path);

  my @module_nodes_list = $xp -> findnodes ('/screens/use-perl-module/text()');

  foreach my $module (@module_nodes_list)
   {
    $module = $module -> string_value;
    debug "storing $module";
    
    push @{$self -> {'modules'}}, "$module";
   }

  my @screen_nodes_list = $xp -> findnodes ('/screens/screen');
  # find all paragraphs

  my $presenters_dir = $self -> {'home'} . '/presentation/' .
                       $self -> {'template-set'} . '/';

  foreach my $screen ( @screen_nodes_list )
   {

    my $id = $screen -> getAttribute ( 'id' );
    next unless defined $id;
    
    my $screen_object = create ACIS::Web::Config::Screen ($id);
    $self -> {'screens'} -> {$id} = $screen_object;
    
    $screen_object -> presentation_type
     ( $xp -> findvalue ('presentation/@type', $screen) );
    
    my $relative_path = $xp -> findvalue ('presentation/@filename', $screen);
    my $absolute_path = $presenters_dir . $relative_path; 
    
    critical "presentation file '$absolute_path' is absent"
     unless ( -f $absolute_path );
    
    $screen_object -> presentation_file ( $relative_path );
     
    my @process_nodes = $xp -> findnodes ('call', $screen);

    foreach my $process ( @process_nodes )
     {
      $screen_object -> add_call( $process -> getAttribute( 'function' ) );
     }
    
    @process_nodes = $xp -> findnodes ('init/call', $screen);

    foreach my $process ( @process_nodes )
     {
      $screen_object -> add_init_call( $process -> getAttribute( 'function' ) );
     }
    
    @process_nodes = $xp -> findnodes ('process/call', $screen);

    foreach my $process ( @process_nodes )
     {
      $screen_object -> add_process_call( $process -> getAttribute( 'function' ) );
     }
    
    my @param_nodes = $xp -> findnodes ('param', $screen); 
    
    foreach my $param ( @param_nodes )
     {
      push @{ $screen_object -> {variables} }, 
       {
        'name'     => undef,
        'required' => undef,
        'type'     => undef,
        'place'    => undef,
       };
      
      foreach my $var ( ('name', 'required', 'type', 'place') )
       {
        $screen_object -> {'variables'} -> [-1] -> {$var} = $param -> getAttribute ($var)
         if $param -> getAttribute ($var);
       }
     }
   }
  return;
}



sub check {
  my $self = shift;
  
  my $presenters_dir = $self -> {'home'} . '/presentation/' .
                       $self -> {'template-set'} . '/';
  
  foreach ( keys %{ $self -> {screens} } ) {
    my $presentation = $self -> screen ($_) -> presentation_file;
  }
}

1;
