#include "alarm.h"
#include "assert.h"

char alarm_string[512];

#define MAX_OTHER 100            	// max number for other alarm type

Alarm alarm_obj;


Alarm::Alarm()
{

	ana_count = 0;
	dig_count = 0;
	alarm_status = 0;	// the global alarm that turns on (1) when there's a new alarm
        alarm_name = "nothing";

     // Initialize everything

     for (int i = 0; i < 35; i++)
     {
      	digital_alarm[i].name = "none";
	digital_alarm[i].status = 0;
      	digital_alarm[i].descr = "nothing";
     }	

     for (int i = 0; i < 50; i++)
     {
        analog_alarm[i].name = "none";
      	analog_alarm[i].status = 0;
      	analog_alarm[i].descr = "nothing";

     }	

     for (int i = 0; i < 100; i++)
     {
        other_alarm[i].name = "none";
      	other_alarm[i].status = 0;
      	other_alarm[i].descr = "nothing";

     }	
        digital_alarm[0].name = "Isolated DC GFI";
	digital_alarm[1].name = "Valves GFI";
	digital_alarm[2].name = "Instrument Bus GFI";
	digital_alarm[3].name = "Logic Bus GFI";
	digital_alarm[4].name = "Lights GFI";
	digital_alarm[5].name = "Toolsled 120VAC GFI";
	digital_alarm[6].name = "Core 120VAC GFI";
	digital_alarm[7].name = "Main 120VAC GFI";
	digital_alarm[8].name = "Port Arm FB Water";
	digital_alarm[9].name = "Aux Heading Water";
	digital_alarm[10].name = "Pan & Tilt Servos Water";
	digital_alarm[11].name = "Thruster Servos Water";
	digital_alarm[12].name = "Doppler Water";
	digital_alarm[13].name = "Altimeter #1 Water";
	digital_alarm[14].name = "Altimeter #2 Water";
	digital_alarm[15].name = "Spare Water";
	digital_alarm[16].name = "Control Can Water";
	digital_alarm[17].name = "Fiber-Optic Can Water";
	digital_alarm[18].name = "FOG Water";
	digital_alarm[19].name = "Transformer Can Water";
	digital_alarm[20].name = "Core/Power Water";
	digital_alarm[21].name = "Spare Water";
	digital_alarm[22].name = "Term Can Water";
	digital_alarm[23].name = "Spare Water";
	digital_alarm[24].name = "";
	digital_alarm[25].name = "";
	digital_alarm[26].name = "";
	digital_alarm[27].name = "";
	digital_alarm[28].name = "";
	digital_alarm[29].name = "";
	digital_alarm[30].name = "";
	digital_alarm[31].name = "";
	
	//---------- Alarm Description ---------------------

	digital_alarm[0].descr = "Ground Fault < 500kOhms";
	digital_alarm[1].descr = "Ground Fault < 500kOhms";
	digital_alarm[2].descr = "Ground Fault < 500kOhms";
	digital_alarm[3].descr = "Ground Fault < 500kOhms";
	digital_alarm[4].descr = "Ground Fault < 500kOhms";
	digital_alarm[5].descr = "Ground Fault < 500kOhms";
	digital_alarm[6].descr = "Ground Fault < 500kOhms";
	digital_alarm[7].descr = "Ground Fault < 500kOhms";
	digital_alarm[8].descr = "Port Arm FB Housing";
	digital_alarm[9].descr = "Aux Heading Housing";
	digital_alarm[10].descr = "Pan & Tilt Servos Housing";
	digital_alarm[11].descr = "Thruster Servos Housing";
	digital_alarm[12].descr = "Doppler Housing";
	digital_alarm[13].descr = "Altimeter #1 Housing";
	digital_alarm[14].descr = "Altimeter #2 Housing";
	digital_alarm[15].descr = "Spare Housing";
	digital_alarm[16].descr = "Control Can Housing";
	digital_alarm[17].descr = "Fiber-Optic Can Housing";
	digital_alarm[18].descr = "FOG Housing";
	digital_alarm[19].descr = "Transformer Can Housing";
	digital_alarm[20].descr = "Core/Power Housing";
	digital_alarm[21].descr = "Spare Housing";
	digital_alarm[22].descr = "Term Can Housing";
	digital_alarm[23].descr = "Spare Housing";
	digital_alarm[24].descr = "";
	digital_alarm[25].descr = "";
	digital_alarm[26].descr = "";
	digital_alarm[27].descr = "";
	digital_alarm[28].descr = "";
	digital_alarm[29].descr = "";
	digital_alarm[30].descr = "";
	digital_alarm[31].descr = "";

	//--------------------- OTHER ALARM -------------------
	// FOG
	other_alarm[0].name = "FOG Parity Error";
	other_alarm[1].name = "FOG Time Out";
	other_alarm[2].name = "FOG CRC Check Error";
	// Transducer
	other_alarm[3].name = "Transducer Parity Error";
	other_alarm[4].name = "Transducer Time Out";
	other_alarm[5].name = "Transducer CRC Check Error";
	// DVL 	
	other_alarm[6].name = "DVL Parity Error";
	other_alarm[7].name = "DVL Time Out";
	other_alarm[8].name = "DVL CRC Check Error";
	// Vision
	other_alarm[9].name = "Vision Parity Error";
	other_alarm[10].name = "Vision Time Out";
	other_alarm[11].name = "Vision CRC Check Error";
	// TMS
	other_alarm[12].name = "TMS Parity Error";
	other_alarm[13].name = "TMS Time Out";
	other_alarm[14].name = "TMS CRC Check Error";
	// Data Log
	other_alarm[15].name = "Data Log Parity Error";
	other_alarm[16].name = "Data Log Time Out";
	other_alarm[17].name = "Data Log CRC Check Error";
	// HDTV
	other_alarm[18].name = "HDTV Parity Error";
	other_alarm[19].name = "HDTV Time Out";
	other_alarm[20].name = "HDTV CRC Check Error";
	// Aux Heading
	other_alarm[21].name = "Aux Heading Error";
	// FIFO
	other_alarm[22].name = "Board Communication Error";
	
	other_alarm[23].name = "Telemetry Write to tty Error";
	
	other_alarm[24].name = "No Ack Ground Fault Select";
	other_alarm[25].name = "No Ack Digital Deafults";	
	other_alarm[26].name = "No Ack Analog Defaults";	
	other_alarm[27].name = "No Ack Teleos Enable";	
	other_alarm[28].name = "No Ack Latitude Setup";
	other_alarm[29].name = "No Ack RPM Setup";	
	other_alarm[30].name = "No Ack Arm Enable";	
	other_alarm[31].name = "No Ack Cam Enable";
	other_alarm[32].name = "No Ack Auto Heading";
	other_alarm[33].name = "No Ack Auto Depth";	
	other_alarm[34].name = "No Ack Auto Cruise";	
	other_alarm[35].name = "No Ack Auto Vision";
	other_alarm[36].name = "No Ack Cam Samples Setup";
	other_alarm[37].name = "No Ack Analog in Gain Offset";	
	other_alarm[38].name = "No Ack Arm Samples Setup";	
	other_alarm[39].name = "No Ack Auto Pilot Setup";	
	other_alarm[40].name = "No Ack Auto Cam Setup";
	other_alarm[41].name = "No Ack Auto Arm Setup";	
	other_alarm[42].name = "No Ack Auto Altitude";
	
	
	
	//------------ Description -------------------
	
	// FOG
	other_alarm[0].descr = "FOG Parity Error";
	other_alarm[1].descr = "FOG Time Out";
	other_alarm[2].descr = "FOG CRC Check Error";
	// Transducer
	other_alarm[3].descr = "Transducer Parity Error";
	other_alarm[4].descr = "Transducer Time Out";
	other_alarm[5].descr = "Transducer CRC Check Error";
	// DVL 	
	other_alarm[6].descr = "DVL Parity Error";
	other_alarm[7].descr = "DVL Time Out";
	other_alarm[8].descr = "DVL CRC Check Error";
	
	
	// Vision
	other_alarm[9].descr = "Vision Parity Error";
	other_alarm[10].descr = "Vision Time Out";
	other_alarm[11].descr = "Vision CRC Check Error";
	// TMS
	other_alarm[12].descr = "TMS Parity Error";
	other_alarm[13].descr = "TMS Time Out";
	other_alarm[14].descr = "TMS CRC Check Error";
	// Data Log
	other_alarm[15].descr = "Data Log Parity Error";
	other_alarm[16].descr = "Data Log Time Out";
	other_alarm[17].descr = "Data Log CRC Check Error";
	// HDTV
	other_alarm[18].descr = "HDTV Parity Error";
	other_alarm[19].descr = "HDTV Time Out";
	other_alarm[20].descr = "HDTV CRC Check Error";
	// Aux Heading
	other_alarm[21].descr = "Aux Heading Error";
	// FIFO
	other_alarm[22].descr = "Board Communication Error";
	
	other_alarm[23].descr = "Telemetry Write to tty error";
	other_alarm[24].descr = "No Ack Ground Fault Select";
	other_alarm[25].descr = "No Ack Digital Deafults";	
	other_alarm[26].descr = "No Ack Analog Defaults";	
	other_alarm[27].descr = "No Ack Teleos Enable";	
	other_alarm[28].descr = "No Ack Latitude Setup";
	other_alarm[29].descr = "No Ack RPM Setup";	
	other_alarm[30].descr = "No Ack Arm Enable";	
	other_alarm[31].descr = "No Ack Cam Enable";
	other_alarm[32].descr = "No Ack Auto Heading";
	other_alarm[33].descr = "No Ack Auto Depth";	
	other_alarm[34].descr = "No Ack Auto Cruise";	
	other_alarm[35].descr = "No Ack Auto Vision";
	other_alarm[36].descr = "No Ack Cam Samples Setup";
	other_alarm[37].descr = "No Ack Analog in Gain Offset";	
	other_alarm[38].descr = "No Ack Arm Samples Setup";	
	other_alarm[39].descr = "No Ack Auto Pilot Setup";	
	other_alarm[40].descr = "No Ack Auto Cam Setup";
	other_alarm[41].descr = "No Ack Auto Arm Setup";	
	other_alarm[42].descr = "No Ack Auto Altitude";	
	
     // set the description for each element
     set_io_alarm_descr();

     // set the description for other alarm type



}



Alarm::~Alarm()
{
      	
	ana_count = 0;
	dig_count = 0;
	alarm_status = 0;	// the global alarm that turns on (1) when there's a new alarm


     // Initialize everything

     for (int i = 0; i < 35; i++)
     {
      	digital_alarm[i].status = 0;
     }	

     for (int i = 0; i < 50; i++)
     {
      	analog_alarm[i].status = 0;
     }	

     for (int i = 0; i < 100; i++)
     {
      	other_alarm[i].status = 0;
     }	



}

void
Alarm::clear_alarm_list()
{

	ana_count = 0;
	dig_count = 0;
	alarm_status = 0;	// the global alarm that turns on (1) when there's a new alarm


     // Initialize everything

     for (int i = 0; i < 35; i++)
     {
      	digital_alarm[i].status = 0;
     }	

     for (int i = 0; i < 50; i++)
     {
      	analog_alarm[i].status = 0;
     }	

     for (int i = 0; i < 100; i++)
     {
      	other_alarm[i].status = 0;
     }	

}


int
Alarm::write_alarm_history()
{
    ofstream outfile;               		/* for outputing to file */
    outfile.open(name.c_str(), ios::out); 	/* open the file */

    if ( !outfile.is_open() )
    {
    	cout <<"ERROR : Can not open file for writing : "<< name << endl;
    	return -1;
    }
    else
    {
    	
    }


}


int
Alarm::set_dig_alarm( int elem_num)
{
     	digital_alarm[elem_num].status = 1;
     	alarm_status = 1;
     	alarm_name = digital_alarm[elem_num].name;
     	
     	return 1;
}


int
Alarm::set_ana_alarm(int elem_num)
{
     	analog_alarm[elem_num].status = 1;
     	alarm_status = 1;
     	alarm_name = analog_alarm[elem_num].name;
     	
     	return 1;
}




int
Alarm::set_other_alarm(int other)
{
     	other_alarm[other].status = 1;
     	alarm_status = 1;
     	alarm_name = other_alarm[other].name;
     	
     	return 1;
}



int
Alarm::add_alarm_to_db(int diganal, int elem_num, string name)
{
        // Analog
	if (diganal == 0)
	{
		//cout<<"alarm.cpp: displaying the analog alarm here \n";
		
		analog_alarm[elem_num].name = name;
		//display_analog_alarm();	
     	
	}
	
	// Digital		
	else
	{
		//cout<<"alarm.cpp: displaying the digital alarm here \n";
		digital_alarm[elem_num].name = name;
		//display_digital_alarm();
	}
	
	
   	return 1;     	
     	 	
     	




}

void
Alarm::set_io_alarm_descr()
{

	cout<<"\n";
  	return ;
  	


}

	
string
Alarm::get_alarm_descr(string name)
{
	
	// traverse the digital alarm array
	for (int i = 1; i <= 32; i++)
	{	 	
		if(digital_alarm[i].name == name)
		{
		 	return digital_alarm[i].descr;
		}	
	}
	
	// traverse the analog alarm array
	for (int i = 1; i <= 48; i++)
	{	
		if(analog_alarm[i].name == name)
		{
		 	return analog_alarm[i].descr;		
		}
	}
	
	
	// traverse the other alarm array
	for (int i = 0; i < MAX_OTHER; i++)
	{	
		if(other_alarm[i].name == name)
		{
		 	return other_alarm[i].descr;		
		}
	}
	
	
	return "no description";
		

}


void 	
Alarm::display_digital_alarm()
{

       	for (int i = 1; i <= 32; i++)
       	{
       		// The name should not be empty, but just needed to avoid seg fault
       		if (digital_alarm[i].name == "\0")
       			break;
       		
       		cout<<"alarm.cpp: digital_alarm["<<i<<"] : "<<digital_alarm[i].name<<endl;
       	                  	
       	}
       	
   	return;
   	
}




void 	
Alarm::display_analog_alarm()
{

       	for (int i = 1; i <= 48; i++)
       	{
       		// The name should not be empty, but just needed to avoid seg fault
       		if (analog_alarm[i].name == "\0")
       			break;
       			        		
       		cout<<"alarm.cpp: analog_alarm["<<i<<"] : "<<analog_alarm[i].name<<endl;
       	
       	}
       	
	return;
   	
}

void
Alarm::reset_alarm()
{
 	alarm_status = 0;

}

void
Alarm::initialize()
{
	IOElement dummy[35];
	

             for (int i = 1; i <= 32; i++)
             {
        		dummy[i].iotype_ = subDigIn;
		dummy[i].element_num_ = i;
	             dummy[i].element_name_ = digital_alarm[i].name;
		if (ioElementControl.pushElement(dummy[i]) == false)
			cout << "alarm.cpp : Cannot create digital alarm object : "<<i<<endl;
		
		//cout <<"alarm.cpp : Successful creating alarm object: "<<i<<endl;
	}




}	
