/***************************************************************************
 *   Copyright (C) 2003-2005 by Michael Goettsche                          *
 *   mail@tuxipuxi.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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <kconfig.h>
#include <kglobal.h>
#include <kled.h>
#include <kfiledialog.h>
#include <kaboutapplication.h>

#include <tqpushbutton.h>
#include <tqlistview.h>
#include <tqlineedit.h>
#include <tqdir.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqbuttongroup.h>
#include <tqcheckbox.h>
#include <tqprocess.h>
#include <tqtextedit.h>
#include <tqframe.h>
#include <tqtimer.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
#include <kdeversion.h>

#include "kstreamripper.h"
#include "addnewstreamimpl.h"
#include "processlistviewitem.h"
#include "processcontroller.h"



KStreamRipper::KStreamRipper( TQWidget* parent, const char* name )
    : KStreamRipperBase( parent,name )
#if KDE_IS_VERSION(3,3,90)
	, m_browser("_shoutcast._tcp",0,true)
#endif
{
    m_destEdit->setText( TQDir::homeDirPath() );
	
    m_streamsListView->addColumn( "Name" );
    m_streamsListView->addColumn( "Status" );
    m_streamsListView->addColumn( "Size" );
	
    //app config
    KConfig *appConfig = KGlobal::config();
	
    m_destEdit->setText( appConfig->readEntry( "Destination" , "" ) );
    m_timeEdit->setText( appConfig->readEntry( "Riptime", "0" ));
    m_tuneInEdit->setText( appConfig->readEntry( "Command", "xmms <url>" ));
    m_id3Checkbox->setChecked( appConfig->readBoolEntry( "Id3Tag", 1 ));
	
    //listview entrys
    TQStringList nameList,urlList,descList;
	
    nameList = appConfig->readListEntry( "names" );
    urlList = appConfig->readListEntry( "urls"  );
    descList = appConfig->readListEntry( "descs" );
    TQStringList::iterator iter1, iter2, iter3;
    iter1 = nameList.begin();
    iter2 = urlList.begin();
    iter3 = descList.begin();
	
    for( ; iter1 != nameList.end() && iter2 != urlList.end() && iter3 != descList.end(); ++iter1, ++iter2, ++iter3 )
	{
            ProcessListViewItem * proc = new ProcessListViewItem( m_streamsListView, *iter1, "", "");
            proc->setRenameEnabled(0, true);
            proc->getProcessController()->setUrl( *iter2 );
            proc->getProcessController()->setDescription( *iter3 );
	}
	
    //CONNECTS
	
    //clicks
    connect(m_addStreamButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(addStreamButtonClicked()));
    connect(m_deleteStreamButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(deleteStreamButtonClicked()));
    connect(m_tuneInButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(tuneInButtonClicked()));
    connect(m_ripButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(ripButtonClicked()));
    connect(m_stopRipButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(stopRipButtonClicked()));
    connect(m_browseButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(browseButtonClicked()));
    connect(m_aboutButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(aboutButtonClicked()));
    connect(m_quitButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(quitButtonClicked()));
	
    //other
    connect( m_streamsListView, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT( selectedNewListItem()) );
    connect( m_DescriptionEdit, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT( descriptionChanged()) );
    connect( m_UrlEdit, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT( urlChanged()) );

    // zeroconf
#if KDE_IS_VERSION(3,3,90)
    connect(&m_browser, TQT_SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)), this,  
            TQT_SLOT(serviceAdded(DNSSD::RemoteService::Ptr)));
    connect(&m_browser, TQT_SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)), this,  
            TQT_SLOT(serviceRemoved(DNSSD::RemoteService::Ptr)));
    m_browser.startBrowse();
#endif
}


KStreamRipper::~KStreamRipper()
{
}


void KStreamRipper::closeEvent( TQCloseEvent *e )
{
    KConfig *appConfig = KGlobal::config();
	
    appConfig->writeEntry( "Destination", m_destEdit->text());
    appConfig->writeEntry( "Riptime", m_timeEdit->text());
    appConfig->writeEntry( "Command", m_tuneInEdit->text());
    appConfig->writeEntry( "Id3Tag", m_id3Checkbox->isChecked());
	
    //save the listview entrys
	
    TQStringList nameList,urlList,descList;
    TQListViewItemIterator iter( m_streamsListView );
	
    while( iter.current() )
	{
            ProcessListViewItem * ProcItem = (ProcessListViewItem*)iter.current();
            if(ProcItem->getProcessController()->getAutomatic()) continue; 
		
            nameList.append( iter.current()->text( 0 ));
            urlList.append( ProcItem->getProcessController()->getUrl() );
            descList.append( ProcItem->getProcessController()->getDescription() );
            ++iter;
	}
	
    appConfig->writeEntry( "names", nameList );
    appConfig->writeEntry( "urls" , urlList  );
    appConfig->writeEntry( "descs", descList );
	
    appConfig->sync();
	
    e->accept();
}


//SLOTS
void KStreamRipper::addStreamButtonClicked()
{
    AddNewStreamImpl *test = new AddNewStreamImpl( this );
    connect( test, TQT_SIGNAL( finished( AddNewStreamImpl* )), this, TQT_SLOT( addStreamFinished( AddNewStreamImpl* )) );
	
    test->show();
}

void KStreamRipper::deleteStreamButtonClicked()
{
    ProcessListViewItem * ProcItem = (ProcessListViewItem*)m_streamsListView->currentItem();
    stopRipButtonClicked();
    delete ProcItem;
}

void KStreamRipper::tuneInButtonClicked()
{
    if( m_streamsListView->currentItem() )
	{
            TQString command = m_tuneInEdit->text().replace( "<url>",  m_UrlEdit->text() );
		
            TQStringList commands = TQStringList::split( " ", command );
		
            TQProcess *process = new TQProcess( TQT_TQOBJECT(this) );
            process->setArguments( commands );
		
            process->start();
	}
    else ;
}

#if KDE_IS_VERSION(3,3,90)
void KStreamRipper::serviceAdded(DNSSD::RemoteService::Ptr srv)
{
    ProcessListViewItem * proc = new ProcessListViewItem( m_streamsListView, srv->serviceName(), "", "");
    proc->getProcessController()->setUrl( TQString("http://%1:%2%3").arg(srv->hostName()).arg(srv->port()).arg(srv->textData()["path"]) );
    proc->getProcessController()->setDescription( i18n("found by Zeroconf") );
    proc->getProcessController()->setAutomatic(true);
    proc->getProcessController()->setService(srv);

}
void KStreamRipper::serviceRemoved(DNSSD::RemoteService::Ptr srv)
{
    TQListViewItemIterator iter( m_streamsListView );
	
    while( iter.current() ) {
            ProcessListViewItem * ProcItem = (ProcessListViewItem*)iter.current();
	    if (ProcItem->getProcessController()->getAutomatic() && 
                srv==ProcItem->getProcessController()->getService()) { 
				delete ProcItem; 
				return; 
				}
	    ++iter;
    }

}
#endif

void KStreamRipper::ripButtonClicked()
{
    if (KStandardDirs::findExe("streamripper")) {
        ProcessListViewItem * ProcItem = (ProcessListViewItem*)m_streamsListView->currentItem();
        ProcItem->getProcessController()->startRip(m_destEdit->text(), m_timeEdit->text());
        m_ripButton->setEnabled( false );
        m_stopRipButton->setEnabled( true );
    } else {
        KMessageBox::error(this, "The streamripper executable wasn't found. Make sure "
                           "it's in your path.", "streamripper not found");
    }
}

void KStreamRipper::stopRipButtonClicked()
{
    ProcessListViewItem * ProcItem = (ProcessListViewItem*)m_streamsListView->currentItem();
    ProcItem->getProcessController()->stopRip();
    m_ripButton->setEnabled( true );
    m_stopRipButton->setEnabled( false );
}

void KStreamRipper::browseButtonClicked()
{
    TQString openDest = KFileDialog::getExistingDirectory( TQDir::homeDirPath(),
                                                          this,
                                                          "Select Destination..." );
    m_destEdit->setText( openDest );
}

void KStreamRipper::aboutButtonClicked()
{
    KAboutApplication *aboutApp = new KAboutApplication();
    aboutApp->show();
}

void KStreamRipper::quitButtonClicked()
{
    this->close();
}

void KStreamRipper::selectedNewListItem()
{
    if ( !m_streamsListView->selectedItem() ) {
        m_deleteStreamButton->setEnabled( false );
        m_tuneInButton->setEnabled( false );
        m_ripButton->setEnabled( false );
        m_DescriptionEdit->setText( TQString() );
	m_DescriptionEdit->setEnabled(false);
	m_UrlEdit->setEnabled(false);
        m_UrlEdit->setText( TQString() );
	return;
    }
    ProcessController * ProcCtl = ((ProcessListViewItem*)m_streamsListView->currentItem())->getProcessController();

    // reconfigure what the user is allowed to do based on if this process is ripping	
    m_ripButton->setEnabled( !ProcCtl->getStatus() );
    m_stopRipButton->setEnabled( ProcCtl->getStatus() );
    m_tuneInButton->setEnabled( true );
    m_deleteStreamButton->setEnabled( !ProcCtl->getAutomatic() );
	
    m_DescriptionEdit->setText(ProcCtl->getDescription());
    m_DescriptionEdit->setEnabled(true);
    m_UrlEdit->setText(ProcCtl->getUrl());
    m_UrlEdit->setEnabled( !ProcCtl->getAutomatic() );

	
    // maybe these are more elegant than the next two functions, assuming the slots are implemented in ProcessController
    //connect(m_DescriptionEdit, TQT_SIGNAL(textChanged(const TQString&)), (ProcessListViewItem*)m_streamsListView->currentItem()->getProcessController(), TQT_SIGNAL(descriptionChanged(const TQString&))
    //connect(m_UrlEdit, TQT_SIGNAL(textChanged(const TQString&)), (ProcessListViewItem*)m_streamsListView->currentItem()->getProcessController(), TQT_SIGNAL(urlChanged(const TQString&))
}

void KStreamRipper::descriptionChanged()
{
    // maybe this should be deleted and the communication would be through a slot
    ProcessListViewItem * ProcItem = (ProcessListViewItem*)m_streamsListView->currentItem();
    ProcItem->getProcessController()->setDescription(m_DescriptionEdit->text());
}

void KStreamRipper::urlChanged()
{
    // maybe this should be deleted and the communication would be through a slot
    ProcessListViewItem * ProcItem = (ProcessListViewItem*)m_streamsListView->currentItem();
    ProcItem->getProcessController()->setUrl(m_UrlEdit->text());
}


void KStreamRipper::addStreamFinished( AddNewStreamImpl *e )
{
    ProcessListViewItem * proc = new ProcessListViewItem( m_streamsListView, e->d_nameEdit->text(), "", "");
    proc->getProcessController()->setUrl( e->d_urlEdit->text() );
    proc->getProcessController()->setDescription( e->d_descEdit->text() );
}

