/**************************************************************************
 * FILE:	io_element_control.h
 * DESCRIPTION:	this will be between the io_interfaces and io_elements
 *************************************************************************/

#ifndef IO_ELEMENT_CONTROL_H
   #define IO_ELEMENT_CONTROL_H

#include <iostream>
#include <string>
#include <vector>
#include <map>

#include "io_poll.h"
#include "io_element.h"
#include "vehicle.h"
#include "./digital_interface/digital_in.h"
#include "../globalHeader.h"

typedef vector<IOElement> topDigInIOList;
typedef vector<IOElement> subDigInIOList;
typedef vector<IOElement> topAnalogInIOList;
typedef vector<IOElement> subAnalogInIOList;
typedef vector<IOElement> topAnalogOutIOList;

typedef vector<IOElement>::iterator digIterator;
typedef vector<IOElement>::iterator anaIterator;
typedef vector<IOElement>::iterator ana_out_iterator;



struct Button
{
	Button *next;	// pointer to the next node
  	string name;
  	string type;
  	string color;
  	int board;
  	int elem_num;
  	int state;
  	int x;
  	int y;
  	int x2;
  	int y2;
  	int width;
  	
  	
};


struct Slidebar
{
	Slidebar *next;	// pointer to the next node
  	string name;
  	string color;
  	int board;
  	int elem_num;
  	float value;
  	int x;
  	int y;
  	int x2;
  	int y2;
  	
};



struct Bar_Detail {

   float min;
   float max;
   float average;
   float yrange;
   float rrange;
   int status;

};


int findIOtype(int, int); 	// helper function for "getIOElement()"



class IOElementControl {
public:
   IOElementControl()									throw();
   ~IOElementControl()									throw();
   bool pushElement(IOElement element)							throw();
   bool moveElement(int, int, int, int new_element_num);
   digIterator getIOElement(int, int, int, digIterator)					throw();
   int	getIOElement(int, int, int)							throw();
   int 	readFromChannel(int, int, int)	 						throw();
   bool enableChannel(IOElement element)						throw();
   bool	retIOString(int, int, int, int, char line[])		throw();
   bool	retDigitalObjString(char objString[], int)		throw();
   bool	retAnalogObjString(char objString[], int)		throw();
   bool	retSubDigitalObjString(char objString[], int)		throw();
   bool	retSubAnalogObjString(char objString[], int)		throw();
   bool 	retTopAnalogOutObjString(char objString[], int index) 	throw();
   int	retDigSize();
   int	retAnaSize();
   int 	retSubDigSize();
   int 	retSubAnaSize();
   int	retAnaOutSize();

   bool	readVoltage(int, int, int, float&, float&, 
		   float&, float&, float&, float&)	throw();
   void 	dump();
   void 	clean_db();
   char*	show_connection_existence(int type );
   int	autoCalibrateMax(int, int, int, float);
   int	autoCalibrateMin(int, int, int, float);
   int	autoCalibratCalc(int, int, int, float);

   float  updateVehAnalog(int elem_num, float analog_val);
   int 	ret_subana_elem_num (int index);

   // ----------------------- OUTPUT -------------------------


   Output_List	*curr_out;   		// can traverse the list of output nodes
   Output_List	*curr_prev;		// for deletion purposes

   void	make_input_output ( int	surfVehicle, int digAnalog,	int element_num, char output_string[] );
   int 	check_io_output_db  (int out_board, int out_elem_num );
   int 	set_out_string( IOElement *some_ptr, Output_List *ptr );
   string 	display_output( int surfVehicle, int digAnalog, int element_num);
   int 	delete_output ( Output_List *ptr );  		// delete all of output nodes
   int 	delete_single_output ( int type, Output_List *ptr );  	// delete one output node
   int       delete_single_input ( int elem_num ); 			// delete input node
   void 	dump_output();
   void 	test_output(int type);
   void 	test_output_helper(Output_List *ptr);
   int 	send_output_down( int surfVehicle, int digAnalog, int element_num, int digitalVal, float analogVal);
   int 	get_graph_info (int index, char graph_string[] );
   int	setting_bar_detail (int elem_num,  float max, float min, float ave, float yrange, float rrange );
   int	getting_bar_detail (int elem_num,  char bar_string[] );


   // ----------------------- BUTTON -------------------------

   Button	*but_ptr;                       	// pointer to traverse the button nodes
   Button	*first_but; 		// pointer to the first node of button node

   int 		check_button_db (string name, int board, int elem_num);
   int 		add_to_button_db ( string name, string type, int out_board, int out_elem_num, int x, int y, string color, int state, int screen );
   int 		remove_button_from_db (int board, int elem_num, int screen);
   void 	display_button_db ();
   int 		get_but_state(int board, int elem_num);
   int 		set_but_state(int board, int elem_num, int state);
   bool 	ret_button_db_string (char objString[], Button *ptr);
   int 		bcount;
   char* 	get_button_string(int index);
   char* 	get_button_name(int board, int elem_num);
   char* 	get_button_color_type(int board, int elem_num);
   char* 	get_bname(int index);
   char* 	get_button_pos(int board, int elem_num, int screen);
   int 		delete_all_buttons();


   // ----------------------- SLIDEBAR -------------------------

   Slidebar	*slide_ptr;                       	// pointer to traverse the slidebar nodes
   Slidebar	*first_slide; 		// pointer to the first node of slidebar node
   				// count the number of slidebar


   int 		check_slidebar_db (string name, int board, int elem_num);
   int 		add_to_slidebar_db ( string name, int out_board, int out_elem_num, float value, int x, int y, string color, int screen );
   int 		remove_slidebar_from_db (int board, int elem_num, int screen);
   void 	display_slidebar_db ();
   float 	get_slide_value(int board, int elem_num);
   bool 	ret_slide_db_string (char objString[], Slidebar *ptr);
   int 		set_slide_value(int board, int elem_num, float value);
   int 		scount;
   char* 	get_slidebar_string(int index);
   char* 	get_slidebar_name(int board, int elem_num);
   char* 	get_sname(int index);
   char* 	get_slidebar_pos(int elem_num, int screen);
   int 		delete_all_slidebars();

   // --------------------- Detritus -----------------------------
   int  Detritus_make();
   int  Detritus_select(int selection);
   void Detritus_initialize();

   // --------------------- Tool ---------------------------------
   int  Tool_make();
   int  Tool_select(int selection);
   void Tool_initialize();

   //-------------------------------------------------------------

   char*	get_element_name(int surveh, int diganal, int elem_num);
   char*  	get_xy_pos(int elem_num, int screen);
   char*	get_master_feedback_arm();
   char*	get_master_feedback_cam();


   //----------------------------------------------------------

   int 		clean_all_ioelem();
   char*	get_button_connection(string name);
   char*	get_slide_connection(string name);
   float 	get_analog_value(int surveh, int elem_num);
   int 		get_digital_value(int surveh, int elem_num);
   char*	get_io_connection(string name);


   //----------------------------------------------------------

   int		get_auto_head_status();
   int		get_auto_depth_status();
   int		get_auto_altitude_status();
   float 	update_depth_value(float raw);			
   int 	 	switch_arm_enable(int status);	
   char* 	get_sit_camera_angle();

 //private:

   topDigInIOList 			topdigitalInList;
   subDigInIOList 			subdigitalInList;
   topAnalogInIOList		topanalogInList;
   subAnalogInIOList 		subanalogInList;
   topAnalogOutIOList		topanalogOutList;

   topDigInIOList::iterator 		currDigIn;
   subDigInIOList::iterator 		currSubDigIn;
   topAnalogInIOList::iterator	 	currAnaIn;
   subAnalogInIOList::iterator	currSubAnaIn;
   topAnalogOutIOList::iterator 	currAnaOut;


   bool inDataBase(IOElement element);
   int send_bottom_analog_down();
   int enabling_dig_channel(int surveh, int diganal, int elem_num, int status);
   int enabling_ana_channel(int surveh, int diganal, int elem_num, int status);
   int get_overlay_channel(string name);

   int count;
   int output_count;

   int send_default_down(int surfVehicle, int digAnalog, int element_num);
   int send_defaults_down();
   int initializeLookup();

   int subout_make();

   /********************** Detritus structures *******************************/

   struct Output_List Detritus[16];
   struct Output_List Tool[16];


   /*************************************************************************/

   Bar_Detail 	bar_detail[50];



};


extern IOElementControl ioElementControl;
#endif
