/***************************************************************************
                          sender.cpp  -  description
                             -------------------
    begin                : Wed Feb 5 2003
    copyright            : (C) 2003-2005 by Christophe Thommeret
    email                : hftom@free.fr
    last modified        : $Date: 2005/04/27 19:38:47 $ by $Author: hftom $
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <kmessagebox.h>
#include <klocale.h>

#include "sender.h"



BChannel::BChannel( const QString &n, unsigned int pv, unsigned int pa, char a, unsigned int spid, unsigned int pg, unsigned int an, unsigned int tp, const QString &lg )
{
	name = n;
	pidv = pv;
	pida = pa;
	ac3 = a;
	subpid = spid;
	page = pg;
	id = an;
	type = tp;
	lang = lg;
}



Sender::Sender()
{
	isRunning = false;
	senderSocket = 0;
	bchan.setAutoDelete( true );
}



bool Sender::makeSenderSocket( const QString &addr, int m_senderPort )
{
	int sockopt=1;

	if ( senderSocket ) return true;

	if ( ( senderSocket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		KMessageBox::error( 0, i18n("Can't open DVB info socket.") );
		senderSocket = 0;
		return false;
	}

	senderAddr.sin_family = AF_INET;         // host byte order
	senderAddr.sin_port = htons( m_senderPort );     // short, network byte order
	senderAddr.sin_addr.s_addr = inet_addr( addr.ascii() );

	memset( &( senderAddr.sin_zero ), '\0', 8 ); // zero the rest of the struct

	if ( setsockopt( senderSocket, SOL_SOCKET, SO_BROADCAST, &sockopt, sizeof(sockopt) ) < 0 ) {
		KMessageBox::error( 0, i18n("Can't open DVB info socket.") );
		close( senderSocket );
		senderSocket = 0;
		return false;
	}
	fprintf( stderr, "Sender socket opened\n" );
	return true;
}



Sender::~Sender()
{
	stop();
}



void Sender::closeSender()
{
	if ( senderSocket ) {
		close( senderSocket );
		senderSocket = 0;
		fprintf( stderr, "Sender socket closed\n" );
	}
}



void Sender::run()
{
	QString list;
	int i;
	BChannel *bc;

	while( isRunning ) {
		list = "";
		for ( i=0; i<(int)bchan.count(); i++ ) {
			bc = bchan.at(i);
			list = list+bc->name+"|"+QString().setNum(bc->pidv)+"|"+QString().setNum(bc->pida)+"|";
			if ( bc->ac3 ) list+= "y|";
			else list+= "n|";
			list+= QString().setNum(bc->subpid);
			list+= "|";
			list+= QString().setNum(bc->page);
			list+= "|";
			list+= QString().setNum(bc->id);
			list+= "|";
			list+= QString().setNum(bc->type);
			list+= "|";
			list+= bc->lang+"|";
		}
		list+="\n";
		sendto( senderSocket, list.latin1(), list.length(), 0, (struct sockaddr *)&senderAddr, sizeof(senderAddr) );
		msleep(500);
	}
}



void Sender::go()
{
	isRunning = true;
	start();
}



void Sender::stop()
{
	isRunning = false;
	if ( !wait(100) ) {
		terminate();
		wait();
	}
	sendto( senderSocket, "quit\n", 5, 0, (struct sockaddr *)&senderAddr, sizeof(senderAddr) );
	closeSender();
}
