/*************************************************************************
 * io_element.h
 * comments added later
 ************************************************************************/

#ifndef IO_ELEMENT_H
   #define IO_ELEMENT_H

#include <cmath>
#include <iostream>
#include <memory>
#include <string>

enum IOTYPE { none = 0,
	      topDigIn, topDigOut, topAnalogIn, topAnalogOut,
              subDigIn, subDigOut, subAnalogIn, subAnalogOut, button_exist, slidebar_exist };

using namespace std;


/************** global variables - help out with grouping ***************/

struct Graphics {
   string type_;
   int x_;
   int y_;
   string type2_;
   int x2_;
   int y2_;
   int color_;
   int vga_screen_;
 //  int touch1_x_, touch1_y_;
 //  int touch2_x_, touch2_y_;   
};


struct DigitalInput {
   unsigned int group;
   unsigned int port;
   unsigned char channel;
};


struct Output_List {

   //Output_List	*prev;   	// points to the first node of output
   Output_List *next;
   Output_List *prev;

   int out_surveh;
   int out_diganal; 	// used for
   int out_elem_num;
   int out_board;	// used for bottom output only

   int out_digital_value;
   float out_analog_value;
   float out_analog_raw;
   float out_analog_gain;
   float out_analog_offset;
   float out_analog_max;
   float out_analog_min;
   //int output_count;
};



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


class IOElement {
	// IOElement is encapsulated to prevent corruption
	// in case of newer classes contain them.
        // The only way to interact with this is through
        // this interface. Any changes that should be
        // made should derive this class and extend 
        // the functionaly and/or variables.
public:
   IOElement()		throw();
   ~IOElement() throw();
   void make(   int	surfVehicle,
		int	digAnalog, 
		int	element_num,
		string	element_name,
   	      	string 	defaults,
		int 	default_level,	
   		bool 	enable_channel,
		bool	auto_calibrate_enable,
   		bool 	enable_graphics,
		int 	digital_value,
   		float 	analog_value,
		float 	analog_raw,
		float	analog_offset,
		float	gain,
 		float	max,
   		float	min,
   	        string	graphic_type,
		int	color,
		int	x,
		int	y,
		int 	vga_screen  ) 	throw(bad_alloc);
 
   string 	name() 				{ return element_name_; };
   int 		num() 				{ return element_num_; };
   int 		getIOtype() 			{ return iotype_; };
   bool 	isChannelenabled() 		{ return enable_channel_; };   
 
   DigitalInput digital_input_info();
   void 	updateDigital_value(int digVal) { digital_value_ = digVal; }; 

   unsigned int getAnaChannel() 		{ return element_num_; };
   void		updateAnalogValue(float value) 	{ analog_value_ = value; };
   void		updateAnalogRaw(float raw)	{ analog_raw_ = raw; };

   void 	getAllInfo(int, int, int, int, char line[]);
   void 	getAllInfo(char retString[]);
   void 	test();
   int 		autoCalibrateMax(int a, int b, int c, float d);
   int 		autoCalibrateMin(int a, int b, int c, float d);

   int get_digital_value() { return digital_value_; };
   float get_analog_value() { return analog_value_; };
   float get_analog_raw() { return analog_raw_; };
   void get_graph_info( char graph_string[] );
   Output_List 	*next_out;
   string out_string;    		// output string board#|elem#|...



   /******************************************
    * Output purposes
    ******************************************/


    //protected:


   int		iotype_;
 
  int		element_num_;
  string	element_name_;
  string 	defaults_;	
   int		default_level_;
   bool 	enable_channel_;
   bool		auto_calibrate_enable_;
   bool 	enable_graphics_;
   int 		digital_value_;
   float 	analog_value_;
   float	analog_raw_;
   float	analog_offset_;
   float	analog_gain_;
   float	max_;
   float	min_;
   Graphics	graphics_;
   DigitalInput	digital_input_;	
   float	tmpMax;
   float 	tmpMin;
   int 		input_io_point_;
   int 		output_io_point_;

   int		usedAutoCalibrate;

   /* helper functions - internal to class */
   int findIOtype(int surfVehicle, int digAnalog);
   void findDigitalInfo();
   int typeToSD(int, int&, int&);






private:
   // add the assigment operator in here 
   // and the copy constructor
   

};

extern IOElement io_element;

#endif
