#include <fstream>     
#include <unistd.h>    
#include <fcntl.h>
#include <sys/termios.h>
#include <sys/ioctl.h>


class Dmm {
  private:
    ifstream me;
    int fd;
    int initTTY(char*);
    int liesMesswert();
    int liesGraph(); 
  public:
    Dmm(char*);
    ~Dmm();
    int liesWert();

};


Dmm::Dmm(char* device){   //Konstruktor
 me.open(device, ios::in);
  //initTTY(device);
  /*me.open(device,ios:app | ios::in);
  if (!me) {
    cerr<<"Device "<<device<<" kann nicht geoeffnet werden!"<< endl;
  exit(1); 
  }
  else {   
    cout << "Device " << device << endl;
  }*/

  initTTY(device);
} 

Dmm::~Dmm(){              //Destruktor
 close(fd);
 me.close();
} 


int Dmm::initTTY(char* device){  //Initialisierung der Schnittstelle

  int modelines = 0;
  fd = open(device, O_RDWR | O_NOCTTY);
  //cout << "fd= " << fd << endl;
  if (fd == -1){
    cerr << "RS-232 kann nicht initialisiert werden!" << endl;
  exit(1);
  }


  struct termios settings;

  //Setzen der Inputflags
  settings.c_iflag = IGNBRK | IGNPAR;
  
  //Setzen der Outputflags
  settings.c_oflag = 0;
  
  //Setzen der Controlflags
  settings.c_cflag = CS8     // 8 Bit pro Byte
                   | CREAD   // Zeichen koennen von gelesen werden
                   | CLOCAL; // Ignoriere Modemstatus, lokaler Anschluss

  //Setzen der Localflags
  settings.c_lflag = 0;      // keine besonderen Angaben noetig

  // Maximale Zeit, die beim Lesen gewartet wird (in 0.1s)
  settings.c_cc[VTIME] = 10; // kleinere Werte für Geräte mit höheren
                             // Übertragungsgeschwindigkeiten 
                             // z.B. Me32 -> 30

  // Minimale Anzahl der zu lesenden Bytes
  settings.c_cc[VMIN] = 0;

  //Setzen der Uebertragungsgeschwindigkeit
  if (cfsetspeed(&settings, B9600)!=0){   //GDM703 hat 9600 Baud !!!
    cerr << "Fehler beim Setzen der Übertragungsgeschwindigkeit" << endl;
  return -1;
  }                 
 
  //Einstellungen an Schnittstelle uebergeben
  if (tcsetattr(fd, TCSANOW, &settings) == -1){
    cerr << "Fehler bei tcsetattr TCSANOW" << endl; 
  return -1;
  }    

}

int Dmm::liesMesswert(){
char ch2;
char val[6]="leer";
float messwert=2;
for (int i=1; i<3; i++){    //Müll vor dem eigentlich Zahlenwert
read(fd,&ch2,1);
}
for (int i=0; i<5; i++){   //Der eigentliche Messwert
    read(fd, &val[i], 1);
    }
  cout << val << endl;
} 
int Dmm::liesGraph(){

char ch2='a';
char val[1024];
int daten[128];
for (int i=0; i<1024 ; i++){
   read(fd,&val[i],1); cout << i << ": "<< (unsigned int)val[i] <<endl;
    }
read (fd,&ch2,1);//EOT holen (3)
cout << "test" << endl;
// cout << i << ": "val << endl;
} 
 
int Dmm::liesWert(){

char ch='a';
cout << "Falls das Graphikdisplay ausgelesen werden soll: 'Storage-call'
drücken!"<<endl; 
while((int)ch != 2){
read(fd,&ch,1);
}
read(fd,&ch,1); //Ein Zeichen holen: was kommt (A,B-Messwert, Z-Graph)
cout << ch << endl;
if (ch=='A' || ch=='B' || ch=='E' || ch=='H' 
|| ch=='J' || ch=='L' || ch=='M') liesMesswert();   //Ein Messwert!
else {if (ch=='Z') {liesGraph();}            //Graphikdaten werden gesendet
else liesWert();}			  //Falls Schwachsinn kommt nochmal
// cout << i << ": "val << endl;
} 

int main(int argc, char* argv[]){
float value;
  Dmm* multimeter;

  if (argc > 1) multimeter = new Dmm(argv[1]);
  else          multimeter = new Dmm("/dev/ttyS0");
  multimeter -> liesWert();
 delete multimeter;
return 0;
}

