/*===========================================================================*/
/*                                                                           */
/*                    Isaac Newton Group of Telescopes                       */
/*                   Roque de los Muchachos Observatory                      */
/*                               La Palma                                    */
/*                                                                           */
/*                        (c) Copyright STFC 2015                            */
/*                                                                           */
/*===========================================================================*/
/*
COMPONENT:
   $Id: tcs_corba_focusrun.cc,v 1.7 2011/12/16 10:52:16 whtsm Exp $

TYPE:
   C++ source-code.

PURPOSE:
   Eanple CORBA C++ focus client for the TCS.
   
USAGE:
   The programme sets the TCS focus.

   Expected command usage is: 

   tcs_focus <focus_demand_in_mm>

   e.g. tcs_focus 98.0 
 
   This is based on the UltraDAS client udas_corba_focusrun.cc 

PERSONNEL:
   Richard Bassom, Computer Software Group, ING.  rab@ing.iac.es
   Frank Gribbin, Computer Software Group, ING. fjg@ing.iac.es 

HISTORY:
   $Log: tcs_corba_focus.cc,v $

   8 May 2015 FJG Initial Version

--- End of module header information ----------------------------------------*/
#ifndef __lint
   const char udas_camera_client_cc[] = "@(#)$Id: udas_corba_focusrun.cc,v 1.7 2011/12/16 10:52:16 whtsm Exp $";
#endif

/*- Feature test switches ---------------------------------------------------*/

/*- System headers ----------------------------------------------------------*/
#include <string>
using namespace std;
#include <iostream>
#include <stdlib.h>
#include <syslog.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>

/* Header-files standardized by ANSI C: */
#include <errno.h>

/*- Local headers -----------------------------------------------------------*/
#include <OCSCorbaDrama.hh>
#include <udas_corba_client.hh>



/*- Local macros ------------------------------------------------------------*/
/*- Local typedefs, structures and unions -----------------------------------*/

/*- External data -----------------------------------------------------------*/
/*- Local data --------------------------------------------------------------*/





class UltradasRunCommandLine
{
   public:

   double      demand_focus;

   private:
   char        command[1024];

   public:
   /**
   // Parse the command line arguments
   */
   void parseCommandLine(int argc, char **argv)
   {
      // Get command line arguments, log them, and check usage
         strcpy(command, "\0");
         for (int i = 0; i < argc; i++) {
            strcat(command, argv[i]); strcat(command, " ");
         }
         syslog(LOG_DEBUG, "Command line: %s", command);

         if (argc != 2) {
            goto EXIT_USAGE;
         }

         errno = 0;
         demand_focus =         atof (argv[1]);

         if (errno != 0)
         {
            goto EXIT_USAGE;
         }

         return;

         EXIT_USAGE:
            cerr << endl;
            cerr << "Usage:" << endl;
            cerr << "       tcs_focus <focus_demand>" << endl;
            cerr << endl;
            exit (EXIT_FAILURE);
   }

};
/*---------------------------------------------------------------------------*/



/**
* The Ultradas OrbController class
*/
class OrbController
{

private:
   CORBA::ORB_var    localOrb;

public:

   OCSCorbaDrama::TCSInterface_var tcs;

/// Destructor
~OrbController()
{
// Completed, so destroy the orbs. Ignore any exception on destroying
//  the localOrb, as it may have been the same as orb.
   try { localOrb->destroy(); } catch (...) {}
//   cout << "OrbController deleted" << endl;
}

/// Get the Object references required for the focus client
void getRefererences(UltradasRunCommandLine thisCommandLine, int argc, char **argv)
{

   char     tcs_context_name[]     = "OCSCorbaDramaInterface";
   char     tcs_name[]             = "TCSActions";

// Get the ORB reference.

   try {
//      localOrb = getOrb(argc, argv, "omniORB4", (char *) "localhost");
      localOrb = getOrb(argc, argv, "omniORB4", (char *) "icsdev.ing.iac.es");

// Get the Tcs reference, and try a status get to test that it is running
      try {
         CORBA::Object_var tcsObj = getObjectReference(localOrb, tcs_context_name, tcs_name);
         tcs = OCSCorbaDrama::TCSInterface::_narrow(tcsObj);
         tcs->getTCSStatusData();
      }
      catch (...) {
         syslog(LOG_ALERT, "ALARM: Cannot connect to TCS.");
         cerr << " WARNING: Cannot connect to TCS." << endl;
         exit(EXIT_FAILURE);
      }
   }
   catch (...) {
      syslog(LOG_ALERT, "ALARM: Cannot get the ORB.");
      cerr << " WARNING: Cannot get the ORB." << endl;
      exit(EXIT_FAILURE);
   }



   }
   

};







/*---------------------------------------------------------------------------*/



/*- Main function -----------------------------------------------------------*/
int main (int argc, char **argv)
{
   double focus;
   OCSCorbaDrama::TCSInterface_var tcs;   
   
// Parse the command line and check usage
   UltradasRunCommandLine thisCommandLine;
   thisCommandLine.parseCommandLine(argc, argv);
///////////////////////////////////////////////////////////////////////////////

// Get the ORB references.
   try {
      OrbController thisOrbController;
      thisOrbController.getRefererences(thisCommandLine, argc, argv);

//////////////////////////////////////////////////////////////////////
// Set the telescope focus

      focus = thisCommandLine.demand_focus;
      tcs = thisOrbController.tcs;
      tcs->setTelescopeFocusAbsolute((::CORBA::Double) focus);

      goto END_SUCCESS; 

   }

   catch(CORBA::COMM_FAILURE& ex) {
      syslog(LOG_DEBUG, "Caught system exception COMM_FAILURE -- unable to contact the object.");
      cerr << "Caught system exception COMM_FAILURE -- unable to contact the "
           << "object." << endl;
   }
   catch(CORBA::SystemException& se) {
      syslog(LOG_DEBUG, "Caught CORBA::SystemException.");
      cerr << "Caught CORBA::SystemException." << endl;
      cerr << "  mesg: " << se._name() << endl;
      cerr << "The camera could not be contacted - please ensure" << endl;
      cerr << "that the camera is running on the DAS machine." << endl;
   }
   catch(CORBA::Exception&) {
      syslog(LOG_DEBUG, "Caught CORBA::Exception.");
      cerr << "Caught CORBA::Exception." << endl;
   }
   catch(omniORB::fatalException& fe) {
      syslog(LOG_DEBUG, "Caught omniORB::fatalException:");
      syslog(LOG_DEBUG, "  file: %s", fe.file());
      syslog(LOG_DEBUG, "  line: %d", fe.line());
      syslog(LOG_DEBUG, "  mesg: %s", fe.errmsg());
      cerr << "Caught omniORB::fatalException:" << endl;
      cerr << "  file: " << fe.file() << endl;
      cerr << "  line: " << fe.line() << endl;
      cerr << "  mesg: " << fe.errmsg() << endl;
   }
   catch(...) {
      syslog(LOG_DEBUG, "Caught unknown exception.");
      cerr << "Caught unknown exception." << endl;
   }
   
   // An Orb failure has occurred, so exit with failure
   exit(EXIT_FAILURE);

//////////////////////////////////////////////////////////////////////
// Completed, so destroy the orb controller - this is done as the program exits
//   delete &thisOrbController;


END_SUCCESS:

// Exit with success
   syslog(LOG_DEBUG, "Completed.");
   return EXIT_SUCCESS;
}

/*- End of main function -----------------------------------------------------*/



/*- Local functions ----------------------------------------------------------*/
