
#include <stdlib.h>
#include <tqcursor.h>
#include <tqsplitter.h>
#include <tdelocale.h>
#include <tqdir.h>
#include <tdeconfig.h>
#include <tqtimer.h>
#include "dndlistbox.h"
#include "listboxlink.h"
#include "linkview.h"
#include "linkview.moc"

// internal class to eat invalid leave envents (i.e. leave that does not leave the rect but just enters the splitter, as styles (like baghira ;) may post install eventfilters that'd cause useless repaints and therefore flicker if the scroller appereance changes ;)
class EventKiller : public TQObject
{
protected:
   virtual bool eventFilter( TQObject *o, TQEvent *e)
   {
      if (e->type() == TQEvent::Leave)
         return ((TQScrollView*)o)->rect().contains(((TQScrollView*)o)->mapFromGlobal (TQCursor::pos()));
      return false;
   }
};

LinkView::LinkView(TQWidget * parent, const char * name, WFlags f):
                   TQScrollView(parent, name, f)
{
   setFrameShape( TQFrame::StyledPanel );
   setFrameShadow( TQFrame::Sunken );
   setBackgroundMode(TQt::PaletteBase);
   _blocked = false;
   splitter = new TQSplitter( TQt::Vertical, viewport() );
   addChild(splitter);
   splitter->setMargin(5);
   splitter->setBackgroundMode(TQt::PaletteBase);
   splitter->setSizePolicy(TQSizePolicy::Expanding,TQSizePolicy::Minimum);
   splitter->setFrameShape( TQFrame::NoFrame );
   splitter->setChildrenCollapsible(true);
   splitter->setHandleWidth( 3 );
   splitter->setOpaqueResize();
   hardware = new MediaListBox(splitter, "hardware");
   splitter->setResizeMode( hardware, TQSplitter::KeepSize );
   hardware->setFrameShape( TQFrame::NoFrame );
   hardware->setHScrollBarMode(TQScrollView::AlwaysOff);
   hardware->setVScrollBarMode(TQScrollView::AlwaysOff);
   locations = new DnDListBox(splitter, "locations");
//    splitter->setResizeMode( locations, TQSplitter::KeepSize );
   locations->setFrameShape( TQFrame::NoFrame );
   locations->setHScrollBarMode(TQScrollView::AlwaysOff);
   locations->setVScrollBarMode(TQScrollView::AlwaysOff);
   // custom area, locations
   loadLinks();
   locations->setCurrentItem(0);
   locations->setSelected( locations->selectedItem(), false );
   hardware->installEventFilter(this);
   connect (hardware, TQ_SIGNAL(highlighted( int )), this, TQ_SLOT(unselectLocations()));
   connect (locations, TQ_SIGNAL(highlighted( int )), this, TQ_SLOT(unselectHardware()));
   connect (hardware, TQ_SIGNAL(scrolled(int,int)), this, TQ_SLOT(scrollBy(int,int)));
   connect (locations, TQ_SIGNAL(scrolled(int,int)), this, TQ_SLOT(scrollBy(int,int)));
   connect (hardware, TQ_SIGNAL(itemNumberChanged(bool)), this, TQ_SLOT(adjustSplitter2Hardware(bool)));
   connect (locations, TQ_SIGNAL(itemNumberChanged(bool)), this, TQ_SLOT(adjustSplitter2Locations()));
   TQTimer::singleShot(50, this, TQ_SLOT(adjustSplitter2Locations()));
   TQTimer::singleShot(60, this, TQ_SLOT(postInstallEventFilter()));
}

static EventKiller *eventKiller = 0L;

LinkView::~LinkView()
{
   
   saveLinks();
   delete eventKiller; eventKiller = 0L;
}

void LinkView::postInstallEventFilter()
{
   eventKiller = new EventKiller;
   installEventFilter(eventKiller);
}

bool LinkView::eventFilter(TQObject *o, TQEvent *e)
{
   if (o != hardware)
      return TQScrollView::eventFilter(o, e);
   if (_blocked || e->type() != TQEvent::Resize)
      return false; // not a resize - non of our business
   TQResizeEvent *rev = (TQResizeEvent*)e;
   if (rev->size().height() == rev->oldSize().height())
      return false; // height didn't change
   int tmpH = rev->size().height() + locations->numRows()*locations->itemHeight()+20;
   if (tmpH < viewport()->height())
      tmpH = viewport()->height();
   if (tmpH != splitter->height())
   {
      _blocked = true;
      splitter->resize ( splitter->width(), tmpH );
      _blocked = false;
   }

   return false;
}

void LinkView::adjustSplitter2Locations()
{
   int tmpH = hardware->height() + locations->numRows()*locations->itemHeight()+20;
   if (tmpH < viewport()->height())
      tmpH = viewport()->height();
   if (tmpH != splitter->height())
      splitter->resize ( viewport()->width(), tmpH );
}

void LinkView::adjustSplitter2Hardware(bool added)
{
   if (added)
   {
      if (hardware->height() < hardware->numRows()*hardware->itemHeight())
         hardware->resize ( hardware->width(), hardware->numRows()*hardware->itemHeight() );
   }
   else
      if (hardware->height() > hardware->numRows()*hardware->itemHeight())
         hardware->resize ( hardware->width(), hardware->numRows()*hardware->itemHeight() );
}

void LinkView::viewportResizeEvent( TQResizeEvent *rev )
{
   int tmpH = hardware->height() + locations->numRows()*locations->itemHeight()+20;
   if (tmpH < rev->size().height())
      tmpH = rev->size().height();
   splitter->resize(rev->size().width(), tmpH);
}

void LinkView::unselectLocations()
{
   if (locations) locations->setSelected( locations->selectedItem(), false );
}

void LinkView::unselectHardware()
{
   if (hardware) hardware->setSelected( hardware->selectedItem(), false );
}

void LinkView::loadLinks()
{
   if (!locations)
      return;
   TDEConfig config(TQDir::homeDirPath() + "/.qt/baghirarc");
   config.setGroup("Sidebar");
   splitter->setSizes(config.readIntListEntry ("Sizes"));
   loadedLinks = (uint)config.readNumEntry("NumLinks", 0);
   locations->blockSignals ( true );
   if (loadedLinks == 0) // no settings stored - load defaults
   {
      locations->insertItem("desktop", i18n("Desktop"), TQDir::homeDirPath()+"/Desktop");
      locations->insertItem("folder_home", getenv("USER"), TQDir::homeDirPath());
      locations->insertItem("kmenu", i18n("Programs"), "programs:/");
   }
   TQString num;
   for (uint i = 0; i < loadedLinks; i++)
   {
      TQString title;
      TQString icon;
      TQString url;
      num.setNum(i);
      title = config.readEntry("Link_"+num+"_Title", "???");
      icon = config.readEntry("Link_"+num+"_Icon", "empty");
      url = config.readEntry("Link_"+num+"_URL", TQDir::homeDirPath());
      locations->insertItem(icon, title, url);
   }
   locations->blockSignals ( false );
}

void LinkView::saveLinks()
{
   if (!locations)
      return;
   TDEConfig *config = new TDEConfig(TQDir::homeDirPath() + "/.qt/baghirarc");
   config->setGroup("Sidebar");
   config->writeEntry("Sizes", splitter->sizes());
   config->writeEntry("NumLinks", (int)locations->count());
   TQString num;
   for (uint i = 0; i < locations->count(); i++)
   {
      num.setNum(i);
      ListBoxLink *current = (ListBoxLink*)locations->item(i);
      config->writeEntry("Link_"+num+"_Title", current->text());
      config->writeEntry("Link_"+num+"_Icon", current->icon());
      config->writeEntry("Link_"+num+"_URL", current->URL());
   }
   // reduced links, remove them from settings
   for (uint i = locations->count(); i < loadedLinks; i++)
   {
      num.setNum(i);
      config->deleteEntry("Link_"+num+"_Title");
      config->deleteEntry("Link_"+num+"_Icon");
      config->deleteEntry("Link_"+num+"_URL");
   }
   delete config;
}
