/*
 *   XPP - The X Printing Panel
 *   --------------------------
 *
 *   cupsHelper - This class was originally written by Michael Goffioul
 *   (e-mail: gofioul@emic.ucl.ac.be) for QTCUPS, another excellent
 *   printing frontend for CUPS. This version has the same functions,
 *   but is more general and it is not dependent on QT.
 *
 *   Thank you for your great work, Michael!
 *
 *   See the header file (cupshelper.h) for an overview of the fields and
 *   methods.
 *
 *   Copyright 2000 by Till Kamppeter and Michael Goffioul
 *
 *   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., 59 Temple Place, Suite 330, Boston, MA
 *   02111-1307  USA
 *
 */

#include "cupshelper.h"
#include "passworddialog.h"

#include <stdio.h>
#include <stdlib.h>
#include <cups/language.h>

//*******************************************************
//* CUPS library callback function for getting password *
//*******************************************************

const char* cupsGetPasswordCB(const char* prompt)
{
	return CupsHelper::cupsGetPassword(prompt);
}

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

char	CupsHelper::host_[256] = "";
int	CupsHelper::port_ = -1;
char    CupsHelper::login_[256] = "";
char    CupsHelper::password_[256] = "";
int     CupsHelper::count_ = 0;

CupsHelper::CupsHelper(){
}
CupsHelper::~CupsHelper(){
}

const char* CupsHelper::host(){
	return host_;
}

int CupsHelper::port(){
	return port_;
}

void CupsHelper::setHostInfo(const char *host, int port){
	strcpy(host_,host);
	cupsSetServer(host_);
	port_ = port;
	ippSetPort(port_);
}

void CupsHelper::setLoginInfo(const char *usr, const char *pwd){
	strcpy(login_,usr);
	cupsSetUser(login_);
	strcpy(password_,pwd);
}

const char* CupsHelper::login(){
	return login_;
}

const char* CupsHelper::password(){
	return password_;
}

ipp_t* CupsHelper::newIppRequest(){
	ipp_t	*request = ippNew();
	request->request.op.request_id = 1;
	cups_lang_t	*lang = cupsLangDefault();
	ippAddString(request,IPP_TAG_OPERATION,IPP_TAG_CHARSET,"attributes-charset",NULL,cupsLangEncoding(lang));
	ippAddString(request,IPP_TAG_OPERATION,IPP_TAG_LANGUAGE,"attributes-natural-language",NULL,lang->language);
	return request;
}

ipp_t* CupsHelper::processRequest(ipp_t *req, const char *res){
	http_t	*HTTP = httpConnect(host_,port_);
	if (!HTTP)
	{
		ippDelete(req);
		return 0;
	}
	ipp_t	*answer = cupsDoRequest(HTTP,req,res);
	httpClose(HTTP);
	if (!answer)
		return 0;
	if (answer->state == IPP_ERROR || answer->state == IPP_IDLE)
	{
		ippDelete(answer);
		return 0;
	}
	return answer;
}

bool CupsHelper::checkHost(){
	http_t	*HTTP = httpConnect(host_,port_);
	if (!HTTP) return false;
	httpClose(HTTP);
	return true;
}

const char* CupsHelper::cupsGetPassword(const char* prompt){
        char login[256];
        const char *password;
	if (count_ == 0 && strcmp(password_,"") != 0) return password_;
	else {
		count_++;
                strcpy(login,login_);
		// open a dialog to ask for password
                password = passworddialog(prompt,login);
                if (password) {
                  setLoginInfo(login,password);
                  return password;
                } else return 0;
	}
}

void CupsHelper::setup(){
	if (strcmp(host_,"") == 0) strcpy(host_,cupsServer());
	if (strcmp(login_,"") == 0) strcpy(login_,cupsUser());
	if (port_ < 0) port_ = ippPort();
	cupsSetPasswordCB(cupsGetPasswordCB);
}

int CupsHelper::printerType(const char *name){
	ipp_t	  *request = newIppRequest();
	char      str[256];
	int	  value(-1);

	request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
	sprintf(str,"ipp://%s:%d/printers/%s",host(),port(),name);
	ippAddString(request,IPP_TAG_OPERATION,IPP_TAG_URI,"printer-uri",NULL,str);
	//sprintf(str,"/printers/%s",name);
	sprintf(str,"/printers/");
	request = processRequest(request,str);
	if (request && request->curtag == IPP_TAG_PRINTER) {
		ipp_attribute_t	*attr = ippFindAttribute(request,"printer-type",IPP_TAG_ENUM);
		if (attr) value = attr->values[0].integer;
	}
	ippDelete(request);
	return value;
}
