/***************************************************************************
 *   Copyright (C) 2005 by James Thorniley                                 *
 *   james@uncommonlygood.co.uk                                            *
 *                                                                         *
 *   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 "burnsidebarplugin.h"
#include "burndevicewidget.h"
#include <stdio.h>
#include <k3bdevicemanager.h>
#include <k3bexternalbinmanager.h>
#include <kinstance.h>
#include <qstring.h>
#include <qwidget.h>
#include <qvbox.h>
#include <klistview.h>
#include <klocale.h>
#include <qwidgetstack.h>
#include <kdirlister.h>
#include <kglobal.h>
#include <kstandarddirs.h>
#include <kurl.h>
#include <kdebug.h>
#include <k3bcore.h>
#include <k3bpluginmanager.h>
#include <qevent.h>
#include <qlayout.h>
#include <kconfig.h>
#include <qcombobox.h>

#include "burnprojecttypewidget.h"
#include "burnaudiocdconfigwidget.h"
#include "burndatacdconfigwidget.h"
#include "burndatadvdconfigwidget.h"
#include "burndevicescanner.h"

KConfig *BurnSidebarPlugin::m_burnConfig = 0;

KConfig *BurnSidebarPlugin::config()
{
  if(!m_burnConfig)
    m_burnConfig = new KConfig( "burnsidebar" );

  return m_burnConfig;
}

BurnSidebarPlugin::BurnSidebarPlugin(
      KInstance *inst,QObject *parent,
      QWidget *widgetParent, 
      QString &desktopName_, 
      const char* name):
      KonqSidebarPlugin(inst,parent,widgetParent,desktopName_,name)
{

  KGlobal::locale()->insertCatalogue("konqsidebar_burn");

  m_dock = (KDockWidget*)widgetParent;
  if( !K3bCore::k3bCore() )
  {
    kdDebug() << "BurnSidebarPlugin: initialising K3bCore" << endl;
    new K3bCore(0);
    K3bCore::k3bCore()->externalBinManager()->search();
    K3bCore::k3bCore()->pluginManager()->loadAll();
    if( !K3bCore::k3bCore()->externalBinManager()->foundBin( "growisofs" )
        || !K3bCore::k3bCore()->externalBinManager()->foundBin( "dvd+rw-format" ) )
      m_enableDVD = false;
    else
      m_enableDVD = true;

  }

  //initialise dir watcher, notifies config widgets when the
  //data directory changes
  m_dataDirLister = new KDirLister( true );
  m_dataDirLister->openURL( KGlobal::dirs()->saveLocation("data", "kio_burn/data") );
  m_dataDirLister->setAutoUpdate( true );

  if( m_dataDirLister->isFinished() )
    addSubDirs();

  connect( m_dataDirLister, SIGNAL( newItems(const KFileItemList &) ),
           this, SLOT( slotNewItems( const KFileItemList & ) ) );


  initGui(widgetParent);

  m_scanner = new BurnDeviceScanner( this );

  m_scanner->start();
}

void BurnSidebarPlugin::handleURL(const KURL &/*url*/)
{

}

void BurnSidebarPlugin::initGui( QWidget *parent )
{
  //kdDebug() << "burn: BurnSidebarPlugin::initGui" << endl;
  m_mainView = new QScrollView(parent);
  m_mainView->setResizePolicy(QScrollView::AutoOneFit);
  m_vbox = new QVBox( m_mainView->viewport() );
  m_vbox->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Maximum );
  m_vbox->setSpacing( 5 );
  m_vbox->setMargin( 5 );
  m_mainView->addChild( m_vbox );

  m_projectView = new BurnProjectTypeWidget( m_enableDVD, m_vbox );
  connect( m_projectView, SIGNAL( discTypeSelected( BurnSidebarPlugin::DiscType ) ),
           this, SLOT( slotDiscTypeSelected( BurnSidebarPlugin::DiscType ) ) );

  m_configWidget = new QWidgetStack( m_vbox );
  m_audioCDConfig = new BurnAudioCDConfigWidget( this, m_configWidget );
  m_dataCDConfig = new BurnDataCDConfigWidget( this, m_configWidget );
  m_dataDVDConfig = new BurnDataDVDConfigWidget( this, m_configWidget );
  m_configWidget->addWidget( m_audioCDConfig );
  m_configWidget->addWidget( m_dataCDConfig );
  m_configWidget->addWidget( m_dataDVDConfig );
  QWidget *temp = new QWidget( m_configWidget );
  m_configWidget->addWidget( temp );
  m_configWidget->raiseWidget(temp);
  m_configWidget->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Expanding );

  //m_docCreator will be maintained as a pointer to the currently visible
  //config widget, which also serves to return k3bdocs for burning.
  m_docCreator = 0;

  m_deviceCombo = new QComboBox( m_vbox );
  m_deviceCombo->insertItem( i18n( "Scanning drives...") );
}

void BurnSidebarPlugin::customEvent( QCustomEvent *e )
{
  //when the bus scanner finishes it will post a QCustomEvent with a pointer to
  //a list of useful devices, here we create widgets for each device
  if( e->type() == QEvent::User )
  {

    QPtrList<K3bDevice::Device> *devices = (QPtrList<K3bDevice::Device>*) (e->data());
    if(devices)
    {

      //get rid of the "Scanning devices..." message
      m_deviceCombo->clear();
 

      m_deviceWidget = new QWidgetStack( m_vbox );

      K3bDevice::Device *current;
      BurnDeviceWidget *w;
      for( current = devices->first(); current; current = devices->next() )
      {
        w = new BurnDeviceWidget( current, m_projectView, this, m_deviceWidget ); 
        m_deviceWidget->addWidget( w, m_deviceCombo->count() );
        m_deviceCombo->insertItem( current->vendor() + " " + current->description() );
        connect( m_projectView, SIGNAL( discTypeSelected( BurnSidebarPlugin::DiscType ) ),
                 w, SLOT( slotDiscTypeSelected( BurnSidebarPlugin::DiscType ) ) );
      }
      m_deviceWidget->raiseWidget( 0 );
      m_deviceWidget->show();
      connect( m_deviceCombo, SIGNAL( activated( int ) ),
               m_deviceWidget, SLOT( raiseWidget( int ) ) );

      if( m_deviceCombo->count() < 2 )
        m_deviceCombo->hide();
      //no one else owns it
      delete devices;
    }
  }
}

void BurnSidebarPlugin::addSubDirs()
{

  //kdDebug() << "burn: BurnSidebarPlugin::addSubDirs" << endl;
  KFileItemList items = m_dataDirLister->items() ;
  
  for( KFileItem *item = items.first(); item; item = items.next() )
  {
    //kdDebug() << "Adding item: " << item->url().path() << endl;
    
    if( item->isDir() )
    {
      //kdDebug()<<  "Adding subdir " << item->url().path().latin1() << endl;
      m_dataDirLister->openURL( item->url(), true, true );
      slotNewItems( m_dataDirLister->itemsForDir(item->url()) );
    }
  }
}
void BurnSidebarPlugin::slotNewItems( const KFileItemList &newItems )
{
  //kdDebug() << "burn: BurnSidebarPlugin::slotNewItems" << endl;
  KFileItem *item;
  KFileItemList items = newItems;
  for( item = items.first(); item; item = items.next() )
  {
    if( item->isDir() )
    {
      //kdDebug()<<  "Adding subdir " << item->url().path().latin1() << endl;
      m_dataDirLister->openURL( item->url(), true, true );
      slotNewItems( m_dataDirLister->itemsForDir(item->url()) );
    }
  }
}

void BurnSidebarPlugin::slotDiscTypeSelected( DiscType type )
{
  if( type == AudioCD )
  {
    m_configWidget->raiseWidget( m_audioCDConfig );
    m_docCreator = m_audioCDConfig;
  }
  else if( type == DataCD )
  {
    m_configWidget->raiseWidget( m_dataCDConfig );
    m_docCreator = m_dataCDConfig;
  }
  else if( type == DataDVD )
  {
    m_configWidget->raiseWidget( m_dataDVDConfig );
    m_docCreator = m_dataDVDConfig;
  }
}
BurnSidebarPlugin::~BurnSidebarPlugin()
{
  delete m_dataDirLister;
  delete m_scanner;
}

extern "C"
{
    KDE_EXPORT void* create_konqsidebar_burn(KInstance *instance,QObject *par,QWidget *widp,QString &desktopname,const char *name)
    {
        return new BurnSidebarPlugin(instance,par,widp,desktopname,name);
    }
};
extern "C" {
        KDE_EXPORT bool add_konqsidebar_burn(QString* fn, QString* param, QMap<QString,QString> *map) {
                Q_UNUSED(param);
                map->insert("Type", "Link");
                map->insert("URL", "");
                map->insert("Icon", "cdwriter_unmount");
                map->insert("Name", i18n("CD Writer"));
                map->insert("Open", "true");
                map->insert("X-KDE-KonqSidebarModule","konqsidebar_burn");
                fn->setLatin1("burnsidebar%1.desktop");
                return true;
        }
};
#include "burnsidebarplugin.moc"

