/****************************************************************************
**
** $Id: ddcprobe.cpp,v 1.3 2002/04/15 09:40:17 hausmann Exp $
**
** Copyright (C) 1999 Calderasystems, Inc
** All rights reserved.
**
** This file is part of the Caldera OpenLinux Installer.
** Original Implementation: 1999 by Troll Tech AS
**
** This file may be distributed under the terms of the Q Public License
** as defined by Troll Tech AS of Norway and appearing in the file
** LICENSE included in the packaging of this file.
**
*****************************************************************************/


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>

#include <qapplication.h>
#include <qregexp.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qmessagebox.h>
#include <qstring.h>
#include <kdebug.h>

#include "ddcprobe.h"

bool DdcProbe::probe( Monitor &monitor )
{
  kdDebug() << "DdcProbe::probe()" << endl;

  QString result;

  FILE *ddcprobeFd = popen( "/usr/sbin/ddcprobe", "r" );
  if ( !ddcprobeFd )
    return false;

  QFile f;
  if ( f.open(IO_ReadOnly, ddcprobeFd) ) {    // file opened successfully
    QTextStream t( &f );        // use a text stream
    result = t.read();
    f.close();
    pclose( ddcprobeFd );
  }

  if (result.isEmpty())
    return false;

  if ( !parse( result, monitor ) )
    return false;

  FILE *ddcxinfoFd = popen( "/usr/sbin/ddcxinfo -modelines", "r" );
  if ( !ddcxinfoFd )
    return false;

  if ( f.open( IO_ReadOnly, ddcxinfoFd ) )
  {
      QTextStream t( &f );
      monitor.modeLines = t.read();
      f.close();
      pclose( ddcxinfoFd );
  }

  return !monitor.modeLines.isEmpty();
}

struct manu2vendor {
	const char *manu,*name;
} manu2vendormap[] = {
	{"CPQ","Compaq"},
	{"PHL","Philips"},
	{"DEL","Dell"},
	{"EIZ","EIZO/Nanao"},
	{"GWY","Gateway"},
	{"OQI","ViewSonic"},
	{"MAG","MAG"},
	{"KDS","KDS"}, // Korea Data Systems
	{"CTX","CTX"},
	{"HSL","Hansol"},
	{"API","Acer"},
	{"MAX","Belinea"},
	{"DWE","Daewoo"},
	{"APP","Apple"},
	{"DEC","DEC"},
	{"DPC","Delta Products"},
	{"FCM","Funay"},
	{"HTC","Hitachi"},
	{"HIT","Hitachi"},
	{"HEI","Hyundai"},
	{"HWP","HP"},
	{"ICL","ICL"},
	{"IBM","IBM"},
	{"MTC","Mitac"},
	{"MEL","Mitsubishi"},
	{"AST","AST"},
	{"ADI","ADI"},
	{"MIR","MIRO"},
	{"NEC","NEC"},
	{"MEI","Panasonic"},
	{"TAT","Tatung"},
	{"NAN","EIZO/Nanao"},
	{"ECS","ECS"},
	{"SAM","Samsung"},
	{"NOK","Nokia"},
	{"PGS","Princeton"},
	{"REL","Relisys"},
	{"SNY","Sony"},
	{"TSB","Toshiba"},
	{"TRL","TRL"},
	{"UNM","Unisys"},
	{"VSC","ViewSonic"},
	{"BRG","Bridge"},
	{"ELS","ELSA"},
	{"ELS","ELSA"},
	{"IVM","Iiyama"},
	{"FUJ","Fujitsu"},
	{"PLB","PLB"},
	{"PTS","ProView"},
	{"SDI","Samsung"},
	{"SML","Smile"},
	{"TVM","TVM"},
        {"ENC","Eizo"}
};

bool DdcProbe::parse( const QString &ddcprobe, Monitor &monitor )
{
  int pos, len, nrnames;
  QString hs, vs, names[4];
  QRegExp manufacturer("Manufacturer: ");

//  kdDebug() << ddcprobe << endl;

  monitor.vendor = "Generic";

  pos = manufacturer.search(ddcprobe, 0);
  if (pos >= 0) {
	  QString manu = ddcprobe.mid(pos+manufacturer.matchedLength());
	  QString nrest;
	  unsigned int i;
	  int	  npos;

	  len	= manu.find("\n");
	  manu	= manu.left(len);
	  while ((npos=manu.find('"'))>=0)
	      manu[npos]=' ';

	  kdDebug() << "found manufacturer " << manu <<endl;
	  for (i=0;i<sizeof(manu2vendormap)/sizeof(manu2vendormap[0]);i++) {
		  if (!strcmp(manu2vendormap[i].manu,manu.latin1())) {
			  monitor.vendor = manu2vendormap[i].name;
			  break;
		  }
	  }
  }

  nrnames = 0;
  for (int i=0;i<4;i++) {
      QRegExp vendorExpr=QString("Monitor details %1:\\s*Name: ").arg(i);
      pos = vendorExpr.search(ddcprobe, 0);
      if (pos >= 0) {
	  QString rest = ddcprobe.mid(pos+vendorExpr.matchedLength());
	  QString nrest;
	  int	  npos;

	  len	= rest.find("\n");
	  nrest	= rest.left(len);
	  while ((npos=nrest.find('"'))>=0)
	      nrest[npos]=' ';
	  if (len > 0)
	      names[nrnames++] = nrest;
      }
  }

  switch (nrnames) {
  case 0: monitor.model	 = "Monitor";
	  break;
  case 1: /* assume we have just 1 name string, which is both vendor/model */
	  pos = names[0].find(' ');
	  if (pos >= 0) {
	    monitor.vendor = names[0].left(pos);
	    monitor.model  = names[0].mid(pos+1);
	  } else {
	    monitor.model  = names[0];
	  }
	  break;
  case 2: default:
	  monitor.vendor = names[0];
	  monitor.model  = names[1];
	  break;
  }
  if ( monitor.vendor == "BL" ) {
	  monitor.vendor = "Philips";
	  monitor.model  = "Brilliance " + monitor.model;
  }
  if ( monitor.vendor == "PHL") monitor.vendor = "Philips";

  QRegExp timing("Timing ranges: ");
  pos = timing.search(ddcprobe, 0);
  if (pos >= 0) {
    if (sscanf(ddcprobe.mid(pos+timing.matchedLength()).latin1(), "horizontal = %d - %d, vertical = %d - %d",
               &monitor.hMin, &monitor.hMax, &monitor.vMin, &monitor.vMax ) == 4)
      return true;
  }
  return false;
}
