// -*- C++ -*-

//
//  klpq
//
//  Copyright (C) 1997 Christoph Neerfeld
//  email:  Christoph.Neerfeld@home.ivm.de or chris@kde.org
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//

#include <qfileinfo.h>
#include <qlistbox.h>
#include <qlist.h>
#include <qstring.h>
#include <qcheckbox.h>

#include <kglobal.h>
#include <kprocess.h>
#include <klocale.h>
#include <kconfig.h>
#include <kmessagebox.h>
#include <kdebug.h>

#include "queueview.h"
#include "klpqspooler.h"

void Spooler::setPrintingCommand( KProcess *proc, QString queue, bool b )
{
  *proc << lpc_path;
  if( b )
    *proc << QString::fromLatin1("start");
  else
    *proc << QString::fromLatin1("stop");
  *proc << queue;
}

void Spooler::statusCommand( KProcess *proc, QString queue )
{
  *proc << lpc_path << QString::fromLatin1("status") << queue;
}

void Spooler::updateCommand( KProcess *proc, QString queue )
{
  *proc << lpq_path << QString::fromLatin1("-P") << queue;
}

void Spooler::setQueuingCommand( KProcess *proc, QString queue, bool b )
{
  *proc << lpc_path;
  if( b )
    *proc << QString::fromLatin1("enable");
  else
    *proc << QString::fromLatin1("disable");
  *proc << queue;
}

QStringList Spooler::removeCommand( QString queue, QString id )
{
  QStringList list;
  list << lprm_path;
  list << QString::fromLatin1("-P");
  list << queue;
  list << id;
  return list;
}

void Spooler::makeTopCommand( KProcess *proc, QString queue, QList<int> ids )
{
  *proc << lpc_path << QString::fromLatin1("topq") << queue;

  for ( QListIterator<int> it(ids); it.current(); ++it )
    *proc << QString::number( *it.current() );
}

void Spooler::parseUpdate( KListView *lb_list, 
			   QListBox *lb_status, QString lpq_in_buffer )
{
  QString temp;
  unsigned int i = 0, j = 0;
  QChar c;
  for( j = 0; j < lpq_in_buffer.length(); j++ )
    {
      c = lpq_in_buffer[j];
      if ( c != '\n' )
	temp += c;
      else
	{
	  if(temp.contains(QString::fromLatin1("Rank")))
	     { i = 1; temp = QString::fromLatin1(""); continue; }
          if( temp.isEmpty() )
            { temp = QString::fromLatin1(""); continue; }
	  if(i == 0) 
	    {
	      lb_status->insertItem(temp);
	    }
	  else
	    {
	      kdDebug() << "appending the following: " << temp << endl;
	      int pos = temp.find(' ');
	      int rank = temp.mid(0, pos - 2).toInt();
	      QString owner = temp.mid(7, 10).stripWhiteSpace();
	      int job = temp.mid(18, 4).toInt();
	      QString filename = temp.mid(23, 38).stripWhiteSpace();
              if (filename == QString::fromLatin1("(standard input)")) filename = i18n("(standard input)");
	      pos = temp.find(' ', 61);
	      int size = temp.mid(61, pos - 61).toInt();

	      MyLVI *lvi = new MyLVI(lb_list,
				     rank, owner, job, filename, size);
	      lb_list->insertItem(lvi);
	    }
	  temp = QString::fromLatin1("");
	}
    }
}

int Spooler::parsePrinting( char *buffer, int len )
{
  unsigned char c;
  int j = 0;
  QString temp;
  while( (c = *(buffer+j)) && j < len )
    {
      j++;
      if ( c >= 128) break;
      if ( c != '\n' )
	temp += c;
      else
	{
	  if(temp.contains(QString::fromLatin1("Privileged")))
	    return -1;
	  temp = QString::fromLatin1("");
	  }
    }
  return 0;
}

int Spooler::parseQueuing( char *buffer, int len )
{
  unsigned char c;
  int j = 0;
  QString temp;
  while( (c = *(buffer+j)) && j < len )
    {
      j++;
      if ( c >= 128) break;
      if ( c != '\n' )
	temp += c;
      else
	{
	  if(temp.contains(QString::fromLatin1("Privileged")))
	    return -1;
	  temp = QString::fromLatin1("");
	}
    }
  return 0;
}

void Spooler::parseStatus( char *buffer, int len, QCheckBox *c_queuing, QCheckBox *c_printing )
{
  unsigned char c;
  int j = 0;
  QString temp;
  while( (c = *(buffer+j)) && j < len )
    {
      j++;
      if ( c >= 128) break;
      if ( c != '\n' )
	temp += c;
      else
	{
	  if(temp.contains(QString::fromLatin1("queuing")))
	    { 
	      if(temp.contains(QString::fromLatin1("disabled")))
		{ c_queuing->setChecked(FALSE); }
	      else
		{ c_queuing->setChecked(TRUE); }
	      temp = ""; continue; 
	    }
	  else if (temp.contains(QString::fromLatin1("printing")))
	    { 
	      if(temp.contains(QString::fromLatin1("disabled")))
		{ c_printing->setChecked(FALSE); }
		else
		  { c_printing->setChecked(TRUE); }
	      temp = QString::fromLatin1(""); continue; 
	    }
	  temp = QString::fromLatin1("");
	}
    }
}

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

SpoolerBsd::SpoolerBsd()
{
  KConfig *config = KGlobal::config();
  config->setGroup(QString::fromLatin1("klpqBsd"));
  lpc_path = config->readEntry(QString::fromLatin1("lpcCommand"));
  QFileInfo fi;
  fi.setFile(lpc_path);
  if( !fi.isExecutable() )
    {
      fi.setFile(QString::fromLatin1("/usr/sbin/lpc"));
      lpc_path = QString::fromLatin1("/usr/sbin/lpc");
      if( !fi.isExecutable() )
	{
	  fi.setFile(QString::fromLatin1("/usr/bin/lpc"));
	  lpc_path = QString::fromLatin1("/usr/bin/lpc");
	  if( !fi.isExecutable() )
	    {
	      KMessageBox::error(0, i18n("Sorry, I can't find your lpc program.\n"
					 "Please check the configuration under Options->Spooler."),
				    i18n("Can't find your lpc program!"));
	      lpc_path = QString::fromLatin1("/usr/sbin/lpc");
	    }
	}
    }
  lpq_path = config->readEntry(QString::fromLatin1("lpqCommand"),
			       QString::fromLatin1("lpq") );
  lprm_path = config->readEntry(QString::fromLatin1("lprmCommand"),
				QString::fromLatin1("lprm") );
  config->writeEntry(QString::fromLatin1("lpcCommand"), lpc_path);
}

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

SpoolerPpr::SpoolerPpr()
{
  KConfig *config = KGlobal::config();
  config->setGroup(QString::fromLatin1("klpqPpr"));
  lpc_path = config->readEntry(QString::fromLatin1("lpcCommand"), QString::fromLatin1("ppop") );
  lpq_path = config->readEntry(QString::fromLatin1("lpqCommand"), QString::fromLatin1("ppop") );
  lprm_path = config->readEntry(QString::fromLatin1("lprmCommand"), QString::fromLatin1("ppop") );
  config->writeEntry(QString::fromLatin1("lpcCommand"), lpc_path);
}

void SpoolerPpr::updateCommand( KProcess * proc, QString queue )
{
  *proc << lpq_path << QString::fromLatin1("lpq") << queue;
}

void SpoolerPpr::setQueuingCommand( KProcess *proc, QString queue, bool b )
{
  if( b )
    *proc << lpc_path << QString::fromLatin1("accept") << queue;
  else
    *proc << lpc_path << QString::fromLatin1("reject") << queue;
}

QStringList SpoolerPpr::removeCommand( QString queue, QString id )
{
  QStringList list;
  list << lprm_path;
  list << QString::fromLatin1("cancel");
  list << QString::fromLatin1("%1-%2").arg(queue).arg(id);
  return list;
}

void SpoolerPpr::makeTopCommand( KProcess *proc, QString queue, QList<int>ids )
{
  QString temp;
  temp = QString::fromLatin1("rush %1-%2").arg( queue );
  *proc << lpc_path;

  for ( QListIterator<int> it(ids); it.current(); ++it )
    *proc << temp.arg( *it.current() );
}

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

SpoolerLprng::SpoolerLprng()
{
  KConfig *config = KGlobal::config();
  config->setGroup(QString::fromLatin1("klpqLprng"));
  lpc_path = config->readEntry(QString::fromLatin1("lpcCommand"));
  QFileInfo fi;
  fi.setFile(lpc_path);
  if( !fi.isExecutable() )
    {
      fi.setFile(QString::fromLatin1("/usr/sbin/lpc"));
      lpc_path = QString::fromLatin1("/usr/sbin/lpc");
      if( !fi.isExecutable() )
	{
	  fi.setFile(QString::fromLatin1("/usr/bin/lpc"));
	  lpc_path = QString::fromLatin1("/usr/bin/lpc");
	  if( !fi.isExecutable() )
	    {
	      KMessageBox::error(0, i18n("Sorry, I can't find your lpc program.\n"
					 "Please check the configuration under Config->Spooler."),
				    i18n("Can't find your lpc program!"));
	      lpc_path = QString::fromLatin1("/usr/sbin/lpc");
	    }
	}
    }
  lpq_path = config->readEntry(QString::fromLatin1("lpqCommand"), QString::fromLatin1("lpq") );
  lprm_path = config->readEntry(QString::fromLatin1("lprmCommand"), QString::fromLatin1("lprm") );
  config->writeEntry(QString::fromLatin1("lpcCommand"), lpc_path);
}

void SpoolerLprng::parseUpdate( KListView *lb_list, 
				QListBox *lb_status, QString lpq_in_buffer )
{
  QString temp;
  unsigned int i = 0, j = 0, k = 0, start = 0;
  QChar c;
  for( j = 0; j < lpq_in_buffer.length(); j++ )
    {
      c = lpq_in_buffer[j];
      if ( c != '\n' )
	temp += c;
      else
	{
	  if(temp.contains(QString::fromLatin1("Rank")))
	     { i = 1; temp = QString::fromLatin1(""); continue; }
          if( temp.length() == 0 )
            { temp = QString::fromLatin1(""); continue; }
	  if(i == 0) 
	    {
	      lb_status->insertItem(temp);
	    }
	  else
	    {
	      temp = temp.simplifyWhiteSpace();
	      k = start = 0;
	      while( temp[k] != ' ' && temp[k] != 0 ) // skip rank
		k++;
	      k++;
	      while( temp[k] != ' ' && temp[k] != 0 ) // skip owner
		k++;
	      k++;
	      start = k;
	      while( temp[k] != ' ' && temp[k] != 0 )
		k++;
	      temp = temp.remove(start, k-start); // remove class

	      int pos = temp.find(' ');
	      int rank = temp.mid(0, pos - 2).toInt();
	      QString owner = temp.mid(7, 10).stripWhiteSpace();
	      int job = temp.mid(18, 4).toInt();
	      QString filename = temp.mid(23, 38).stripWhiteSpace();
              if (filename == QString::fromLatin1("(standard input)")) filename = i18n("(standard input)");
	      pos = temp.find(' ', 61);
	      int size = temp.mid(61, pos - 61).toInt();

	      MyLVI *lvi = new MyLVI(lb_list,
				     rank, owner, job, filename, size);
	      lb_list->insertItem(lvi);
	    }
	  temp = QString::fromLatin1("");
	}
    }
}

int SpoolerLprng::parsePrinting( char *buffer, int len )
{
  unsigned char c;
  int j = 0;
  QString temp;
  while( (c = *(buffer+j)) && j < len )
    {
      j++;
      if ( c >= 128) break;
      if ( c != '\n' )
	temp += c;
      else
	{
	  if(temp.contains(QString::fromLatin1("permission")))
	    return -1;
	  temp = QString::fromLatin1("");
	  }
    }
  return 0;
}

int SpoolerLprng::parseQueuing( char *buffer, int len )
{
  unsigned char c;
  int j = 0;
  QString temp;
  while( (c = *(buffer+j)) && j < len )
    {
      j++;
      if ( c >= 128) break;
      if ( c != '\n' )
	temp += c;
      else
	{
	  if(temp.contains(QString::fromLatin1("permission")))
	    return -1;
	  temp = QString::fromLatin1("");
	}
    }
  return 0;
}

void SpoolerLprng::parseStatus(char *buffer, int len, QCheckBox *c_queuing, QCheckBox *c_printing)
{
  unsigned char c;
  int j = 0;
  int i = 0;
  QString temp;
  while( (c = *(buffer+j)) && j < len )
    {
      j++;
      if ( c >= 128) break;
      if ( c != '\n' )
	temp += c;
      else
	{
	  if( !temp.contains(QString::fromLatin1("Printer")) )
	    {
	      temp = temp.simplifyWhiteSpace();
	      i = temp.find(' ')+1;
	      if( temp.mid(i, 2) == QString::fromLatin1("di") )
		{ c_printing->setChecked(FALSE); }
	      else
		{ c_printing->setChecked(TRUE); }
	      if( temp.mid(temp.find(' ', i)+1, 2 ) == QString::fromLatin1("di") )
		{ c_queuing->setChecked(FALSE); }
	      else
		{ c_queuing->setChecked(TRUE); }
	    }
	  temp = QString::fromLatin1("");
	}
    }
}
