=head1 NAME

CFX5::CCLI::ExecutableSelection - handle the EXECUTABLE SELECTION object

=head1 DESCRIPTION

Handle interpretation of the EXECUTABLE SELECTION object in CCL

  $Id$

user interfaces are always complicated. :-(

=cut

package CFX5::CCLI::ExecutableSelection;

use strict;

use CFX5::PkgLoader qw(cfx5_require);

use CFX5::Output qw(:all);

our %attrcclmap = (double => 'Double Precision',
                   int64  => 'Large Problem');

sub set {
  my $this=shift;
  my $db=shift;
  my $root=shift;
  my $groot=shift;

  # Initializaton
  cfx5_require('CFX5::Attr');
  my $atts=CFX5::Attr->new(@_);
  my $origatts=$atts->clone();

  _debug("Setting executable attributes to", scalar($atts->get_attr_list()));

  # Set logical CCL parameters
  while (my ($attrname, $paramname) = each %attrcclmap) {
    if ($atts->get_attr($attrname)) {
      $db->set_ccl_parm("$root/$paramname","Yes");
      $atts->clear_attr($attrname);
    } elsif ($db->have_ccl_parm("$root/$paramname") or (defined $groot and $db->have_ccl_parm("$groot/$paramname"))) {
      # if we've got it, we have to reset it explicitly
      $db->set_ccl_parm("$root/$paramname","No");
    }
  }

  # now we need to save any remaining attributes
  my $attrs=$atts->opartial_attr_list();
  if ($attrs) {
    $db->set_ccl_parm("$root/Attribute List", $attrs);
  }

  # and return what we have ... which is just what we were given,
  # but with the default ones stripped out.  TODO: what do we do
  # about debug?
  return scalar($origatts->partial_attr_list());
}

sub get {
  my $this=shift;
  my $db=shift;
  my $root=shift;
  my $groot=shift;

  # these are taken from the CCL API object :-(
  my $trueRE = '\s*(yes|true|y|t|on)\s*';   # RE to match true values
  my $falseRE = '\s*(no|false|f|n|off)\s*';  # RE to match false values

  # Initialization
  cfx5_require('CFX5::Attr');
  my $gatts;
  if(defined $groot){
    $gatts=$this->get($db, $groot);
  }
  my $atts;
  if($gatts){
   $atts=CFX5::Attr->new($gatts);
  } else {
   $atts=CFX5::Attr->new();
  }
  my $have='';

  # Get attributes from 'Attribute List' CCL parameter
  if ($db->have_ccl_parm("$root/Attribute List")) {
    $have++;
    $atts->specify_attr_list($db->read_ccl_parm("$root/Attribute List"));
  }
  elsif (defined $groot and $db->have_ccl_parm("$groot/Attribute List")){
    $have++;
    $atts->specify_attr_list($db->read_ccl_parm("$groot/Attribute List"));
  }

  # Get attributes from logical CCL parameters
  while (my ($attrname, $paramname) = each %attrcclmap) {
    my $tog = undef;
    if ($db->have_ccl_parm("$root/$paramname")) {
      $have++;
      $tog=$db->read_ccl_parm("$root/$paramname");
    }
    elsif ( defined $groot and $db->have_ccl_parm("$groot/$paramname") ){
      $have++;
      $tog=$db->read_ccl_parm("$groot/$paramname");
    }
    if(defined $tog){
      if ($tog =~ m!^\s*$trueRE\s*$!io) {
        $atts->set_attr($attrname);
      } elsif ($tog =~ m!^\s*$falseRE\s*$!io) {
        $atts->clear_attr($attrname);
      } else {
        if ($tog) {
          $atts->set_attr($attrname);
        } else {
          $atts->clear_attr($attrname);
        }
      }
    }
  }

  # Return list of non-default attributes, if set
  if ($have) {
    my $rv=scalar($atts->partial_attr_list());
    if(defined $rv and $rv){
      return $rv;
    }
    return undef;
  } else {
    return undef;
  }
}

1;
