=head1 NAME

CFX5::CCLI::Simple - simple CCL database object for CFX5::CCLI::Defaulted

=head1 SYNOPSIS

  my $db=CFX5::CCLI::Simple->new($api);
  $obj=CFX5::CCLI::Defaulted->new($db);

=head1 DESCRIPTION

This file provides a simple set of stubs which provide the CCL
database object required by CFX5::CCLI::Defaulted, for instances where
you do not want to use a specialist database.

=cut

package CFX5::CCLI::Simple;

use strict;

use CFX5::CCLI;

use CFX5::Output qw(:all);

sub new {
  my $this=shift;
  my $class=ref($this) || $this;
  my $self={};
  bless $self,$class;
  $self->initialize(@_);
  $self;
}

sub initialize {
  my $self=shift;
  my $api;
  if (@_) {
    $api = shift;
  } else {
    $api = CFX5::CCLI::new_api_object();
  }
  $self->{__PACKAGE__ . '::api'} = $api;
}

sub api {
  my $self=shift;
  $self->{__PACKAGE__ . '::api'};
}

# CFX5::Job provides this, we might as well too
sub ccl_api_obj {
  $_[0]->api();
}

sub format_ccl_error {
  my $self=shift;
  return CFX5::CCLI::format_ccl_error(@_);
}

sub dump {
  my $self=shift;
  my @rv;
  my $rv=$self->api()->getExpandedCCL(\@rv);
  if ($rv) {
    die $rv;
  }
  print join("\n",@rv,'');
}

sub read_ccl_parm {
  my $self=shift;
  my $cp=shift;
  my $c;

  my $api=$self->api();
  if ($api->haveParameter("$cp")) {
    my $rv=$api->getStringValue("$cp",\$c);
    if (defined $rv) {
      _error("Error getting $cp from Command Language database:\n",
	     $self->format_ccl_error($rv));
    }
  } else {
    return undef;
  }

  $c =~ s!\\\#!\#!g;

  $c;
}

sub have_ccl_parm {
  my $self=shift;
  my $cp=shift;

  my $api=$self->api();
  return $api->haveParameter("$cp");
}

=head4 set_ccl_parm

  $deffile=$self->set_ccl_parm('/SIMULATION CONTROL/EXECUTION CONTROL/RUN DEFINITION/Solver Input File', "file.def");

Sets a parameter in the internal copy of the CCL API.  This is an
internal call, which does no checking or updating of status; for
normal usage, see C<set_ccl_parm>.

If the first parameter is a reference to a hash, it is taken as a set
of options (as is done in, for example, L<CGI>).  The
currently-available options are listed under C<set_ccl_parm>.

=cut

sub set_ccl_parm {
  my $self=shift;
  my $api=$self->ccl_api_obj();
  my $opts=(ref $_[0] eq 'HASH' ? shift : {});
  my $cp=shift;
  my $c=shift;

  unless (defined $c) {
    internal_error("Cannot set CCL parameter \"$cp\" to undefined value");
  }

  $c =~ s!\#!\\\#!g;

  if ($api->haveParameter($cp)) {
    # if we already have it, we can just set it like this, as it is
    # more efficient (?)
    my $rv=$api->setStringValue("$cp",$c);
    if (defined $rv) {
      _error("Error setting $cp in Command Language database:\n",
             $self->format_ccl_error($rv));
    }
  } else {
    # we construct a snippet of CCL which we can send to the API to
    # parse, as setStringValue does not allow creation of objects.
    my @path=split(m!/!,$cp);
    shift @path; # remove leading blank
    my $pname=pop @path;
    my @ccl;
    for my $n (@path) {
      if ($n =~ m/:/) {
        push @ccl , "$n";
      } else {
        push @ccl, "$n:";
      }
    }
    push @ccl , "$pname = $c";
    for my $n (@path) {
      push @ccl, "END";
    }
    my $rv=$api->parseCCLData(\@ccl,($opts->{library} ? 1 : 0));
    if (defined $rv) {
      _error("Error setting $cp in Command Language database:\n",
             $self->format_ccl_error($rv));
    }
  }

  $c;
}

1;
