// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

#include <sm_sun_b.h>

sunview_batch_mode* sunbmode;


//constructor
sunview_batch_mode::sunview_batch_mode(const char* filename, const float rev) :
  batch_mode(filename, rev)
{ _generate_command_list();
  _initialise();
}

//destructor
batch_mode::~batch_mode(void)
{ }

void sunview_batch_mode::_generate_command_list(void)
{ // generate the list of known commands;
  known_commands += "!";
  dispatch_functions += &batch_mode::_batch_file_comment;

  known_commands += "COMMENT";
  dispatch_functions += &batch_mode::_comment;

  known_commands += "ECHO";
  dispatch_functions += &batch_mode::_echo;

  known_commands += "INFILETYPE";
  dispatch_functions += &batch_mode::_infiletype;
 
// _open is overloaded, so we need the following trick
//  typedef int (batch_mode::*PMFSS)(DREstring&, DREstring&);
  
  known_commands += "OPEN";
  dispatch_functions += &batch_mode::_Open; 

  known_commands += "PLOT";
  dispatch_functions += &batch_mode::_plot;
  
  known_commands += "PLOTMODE";
  dispatch_functions += &batch_mode::_plotmode;
  
  known_commands += "VERSION";
  dispatch_functions += &batch_mode::_version;

  known_commands += "EXIT";
  dispatch_functions += &batch_mode::_exit;
  
  known_commands += "SHOW";
  dispatch_functions += &batch_mode::_show;
  
  known_commands += "PLOTALL";
  dispatch_functions += &batch_mode::_plotall;  

  known_commands += "SET";
  dispatch_functions += &batch_mode::_set;

  known_commands += "VERBOSE";
  dispatch_functions += &batch_mode::_verbose_toggle;
 
  known_commands += "FIRST"; 
  dispatch_functions += &batch_mode::_first;
  
  known_commands += "NEXT";
  dispatch_functions += &batch_mode::_next;
}
  
//initialise things
void sunview_batch_mode::_initialise(void)
{ batch_mode::initialise();
}

// SET command
int batch_mode::_set(DREstring& c, DREstring& p)
{ enum {QUERY = 1, DURATION, SCMODE, PRAMODE, STARTCHANNEL, ENDCHANNEL,
        PLOTMODE, FILETYPE, DISPLAY, PRINTER};

  glist valid_parms;
  
  valid_parms += "?";			// must be first
  valid_parms += "DURATION";
  valid_parms += "SCMODE";
  valid_parms += "PRAMODE";
  valid_parms += "STARTCHANNEL";
  valid_parms += "ENDCHANNEL";
  valid_parms += "PLOTMODE";
  valid_parms += "FILETYPE";
  valid_parms += "DISPLAY";
  valid_parms += "PRINTER";
  
  int subcommand_number;
  DREstring subcommand;
  const int space_position = find(p, " ");
  
  if (space_position) then
    subcommand = subDREstring(p, 1, space_position - 1).toupper();
  else
    subcommand = p.toupper();
  if (!(subcommand_number = valid_string(subcommand, valid_parms))) then
    error((DREstring)"in _set(DREstring&, DREstring&) : command " + c +
          (DREstring)" " + p + (DREstring)" unknown");
 
  switch (subcommand_number)
  { case QUERY :
             { DREstring command_list;
               for (int n = 2; n <= valid_parms.length(); n++)
               { command_list += (DREstring)(char*)valid_parms[n];
                 command_list += "\r\n";
               }
               error((DREstring)"\r\nvalid subcommands are: \r\n" + command_list);
               break;
             }
    case DURATION : 
             Duration = atoi(subDREstring(p, space_position + 1));
             verbose((DREstring)"Plot duration now " + DREstring(Duration, 10));
             break;
    case SCMODE : 
             _set_scmode(subDREstring(p, space_position + 1));
             break;
    case PRAMODE : 
             _set_pramode(subDREstring(p, space_position + 1));
             break;
    case STARTCHANNEL : 
             Start_channel = atoi(subDREstring(p, space_position + 1));
             verbose((DREstring)"Start channel now " + DREstring(Start_channel, 10));
             break;
    case ENDCHANNEL : 
             End_channel = atoi(subDREstring(p, space_position + 1));
             verbose((DREstring)"End channel now " + DREstring(End_channel, 10));
             break;
    case PLOTMODE : 
             _set_plotmode(subDREstring(p, space_position + 1));
             break;
    case FILETYPE : 
             _infiletype((DREstring)"SET FILETYPE",
                         subDREstring(p, space_position + 1));
             break;
    case DISPLAY : 
             _set_display(subDREstring(p, space_position + 1));
             break;
    case PRINTER : 
             _set_printer(subDREstring(p, space_position + 1));
             break;
    
  }
  return 0;
}

// SHOW command
int batch_mode::_show(DREstring& c, DREstring& p)
{ glist valid_parms;
  
  valid_parms += "SCMODES";
  valid_parms += "TIMES";
  valid_parms += "PRAMODES";
  valid_parms += "SCMODE";
  valid_parms += "PRAMODE";
  valid_parms += "DURATION";
   
  p.toupper();
  switch (valid_string(p, valid_parms))
  { case 0 : _invalid_parameter(c, p);
    case 1 : _show_sc_modes(); break;
    case 2 : _show_range(); break;
    case 3 : _show_pra_modes(); break;
    case 4 : _show_sc_mode(); break;
    case 5 : display_status((DREstring)"Current PRAMODE is : " +
                  _pra_mode_name[Current_pra_mode]); break;
    case 6 : display_status((DREstring)"Duration is : " + DREstring10(Duration));
                  break;
  }
  return 0;
}

// read and execute the file
void sunview_batch_mode::execute(void)
{ istream& input = *file;
  while ((input >> command_line).good())
  
// get the command word
  { if (!command_line.length()) then
      continue;
    
    const int space_position = find(command_line, " ");
    DREstring command;
    int command_number;
  
    if (echo)
      cout << command_line << "\n";
    
    if (space_position) then
      command = subDREstring(command_line, 1, space_position - 1).toupper();
    else
      command = command_line.toupper();
  
    if (!(command_number = valid_string(command, known_commands))) then
    { cerr << "Error in execute() : command `" << command << "' unknown\n";
      exit(-2);
    }

// execute the command, passing the remainder of the command line
    DREstring parameters;
    if (space_position) then
      parameters = subDREstring(command_line, space_position + 1);
  
    typedef int (batch_mode::*PMFSS)(DREstring&, DREstring&);
    PMFSS _dispatch_function = dispatch_functions[command_number];

    (this->*_dispatch_function)(command, parameters);
  }
}

void sunview_batch_mode::display_status(DREstring& msg)
{ cout << "Status : " << msg << "\n"; }


