/***************************************************************************
 *   Copyright (C) 2004 by Thomas Lübking                                  *
 *   thomas@home                                                           *
 *                                                                         *
 *   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 "bab.h"
#include <tqpushbutton.h>
#include <tqcheckbox.h>
#include <tqcombobox.h>
#include <tqdir.h>
#include <tqlayout.h>
#include <tqsettings.h>
#include <tqtabwidget.h>
#include <tqtooltip.h>
#include <tqtimer.h>
#include <tqvbox.h>
#include <tqpainter.h>
#include <dcopclient.h>
#include <tdeapplication.h>
// #include <tdeconfig.h>
#include <kiconloader.h>
#include <tdeaboutdata.h>
#include <tdecmdlineargs.h>
#include <kipc.h>
#include <klibloader.h>
#include <tdelocale.h>
#include <kprocess.h>

#include <twin.h>

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/shape.h>

#include "styleconfdialog.h"

static const char description[] =
    I18N_NOOP("Baghira Aqua/Brushed");

static const char version[] = "cvs";

static TDECmdLineOptions options[] =
{
//    { "+[URL]", I18N_NOOP( "Document to open." ), 0 },
    TDECmdLineLastOption
};

int main(int argc, char **argv)
{
   TDEAboutData about("baghira-switcher", I18N_NOOP("BAB - Baghira Aqua/Brushed Switcher"), version, description,
                  TDEAboutData::License_GPL, "(C) 2004/2005 Thomas Lübking", 0, 0, "baghira-style@gmx.net");
   about.addAuthor( "Thomas Lübking", 0, "baghira-style@gmx.net" );
   TDECmdLineArgs::init(argc, argv, &about);
   TDECmdLineArgs::addCmdLineOptions( options );
   TDEApplication app;
   DCOPClient* client = app.dcopClient();
   client->registerAs( "bab", false);
   client->setDefaultObject( "babInterface" );
   bab* mainBAB = 0;
   mainBAB = new bab;
   app.setMainWidget(mainBAB);
   Corner leftCorner(Corner::left);
   Corner rightCorner(Corner::right);

   KWin::setShadowSize(leftCorner.winId(), 0);
   KWin::setShadowSize(rightCorner.winId(), 0);

   if (!mainBAB->cornerCheck->isChecked())
   {
      leftCorner.hide();
      rightCorner.hide();
   }
   leftCorner.connect( mainBAB->cornerCheck, SIGNAL(toggled(bool)), SLOT(toggle(bool)) );
   rightCorner.connect( mainBAB->cornerCheck, SIGNAL(toggled(bool)), SLOT(toggle(bool)) );

   int ret = app.exec();
   if (mainBAB) delete mainBAB;
   return ret;
}


bab::bab() : TDEMainWindow(0,"bab",TQt::WStyle_StaysOnTop | TQt::WX11BypassWM ){
   bSwitcher = new BabSwitcher(this,"switcher");
   TQToolTip::add(bSwitcher, i18n("leftclick toggles state<br>rightclick toggles setupmenu"));
   bSwitcher->show();
    
   TQDir d( TQDir::homeDirPath() + "/.baghira");
   if (!d.exists())
       d.mkdir(TQDir::homeDirPath() + "/.baghira");
   d = TQDir( TQDir::homeDirPath() + "/.baghira/.bab");
   if (!d.exists())
       d.mkdir(TQDir::homeDirPath() + "/.baghira/.bab");
   FILE *file = NULL;
   TQString tmpString = TQDir::homeDirPath() + "/.baghira/Jaguar";
   if (!TQFile::exists(tmpString))
   {
      if( (file = fopen(tmpString.latin1(), "w")) != NULL )
      {
         fprintf(file,"0\n0\n0\n0\n0\n1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n1\n");
         fclose(file);
      }
   }
   tmpString = TQDir::homeDirPath() + "/.baghira/Panther";
   if (!TQFile::exists(tmpString))
   {
      if( (file = fopen(tmpString.latin1(), "w")) != NULL )
      {
         fprintf(file,"1\n1\n1\n1\n1\n1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n1\n");
         fclose(file);
      }
   }
   tmpString = TQDir::homeDirPath() + "/.baghira/Brushed";
   if (!TQFile::exists(tmpString))
   {
      if( (file = fopen(tmpString.latin1(), "w")) != NULL )
      {
         fprintf(file,"2\n2\n1\n2\n1\n1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n0\n");
         fclose(file);
      }
   }
   tmpString = TQDir::homeDirPath() + "/.baghira/Tiger";
   if (!TQFile::exists(tmpString))
   {
      if( (file = fopen(tmpString.latin1(), "w")) != NULL )
      {
         fprintf(file,"3\n3\n1\n1\n0\n1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n-1\n1\n");
         fclose(file);
      }
   }
   tmpString = TQDir::homeDirPath() + "/.baghira/Milk";
   if (!TQFile::exists(tmpString))
   {
      if( (file = fopen(tmpString.latin1(), "w")) != NULL )
      {
         fprintf(file,"4\n4\n4\n4\n1\n0\n-592138\n-4930834\n-1\n-16777216\n-13009982\n-1\n-16777216\n-1116417\n1\n");
         fclose(file);
      }
   }
   
   TQVBox *vb = new TQVBox(this);
   vb->setLineWidth(2);
   vb->setMargin(2);
//    vb->setFrameStyle(TQFrame::Panel | TQFrame::Plain );
   
   TQLabel *DefStyleLabel = new TQLabel("Default Style is", vb);
   DefStyle = new TQComboBox(vb);
   DefStyle->insertItem ( "Jaguar" );
   DefStyle->insertItem ( "Panther" );
   DefStyle->insertItem ( "Brushed" );
   DefStyle->insertItem ( "Tiger" );
   DefStyle->insertItem ( "Milk" );
   cornerCheck = new TQCheckBox("Round upper screen corners", vb);
   TQSettings config;
   config.beginGroup("/baghira/BAB");
   DefStyle->setCurrentItem(config.readNumEntry("defaultState", BabSwitcher::Panther ));
   cornerCheck->setChecked( config.readBoolEntry("roundCorners", true ) );
   config.endGroup();
   TQPushButton *configBaghira = new TQPushButton("Configure Baghira", vb);
   TQPushButton *Quit = new TQPushButton("Quit BAB", vb);
   TQPushButton *Close = new TQPushButton("Close Menu", vb);
   vb->adjustSize();
   bSwitcher->setStyle(DefStyle->currentText());
   bSwitcher->setDeco(DefStyle->currentText());
   
   connect(DefStyle, SIGNAL(activated(int)), this, SLOT(saveSettings()));
   connect(cornerCheck, SIGNAL(toggled(bool)), this, SLOT(saveSettings()));
   connect(configBaghira, SIGNAL(clicked()), this, SLOT(configureBaghira()));
   connect(Close, SIGNAL(clicked()), this, SLOT(hide()));
   connect(Quit, SIGNAL(clicked()), this, SLOT(close()));
   
   resize(vb->width(),vb->height());
   
//   show();
}

bab::~ bab()
{
   bSwitcher->setStyle(DefStyle->currentText());
   bSwitcher->setDeco(DefStyle->currentText());
   if (bSwitcher) delete bSwitcher;
}

/*Taken from kcontrol, tdecmshell style*/
void bab::configureBaghira()
{

   
   // Use KLibLoader to get the library, handling
   // any errors that arise
   KLibLoader* loader = KLibLoader::self();
   
   KLibrary* library = loader->library( TQFile::encodeName("tdestyle_baghira_config") );
   if (!library)
   {
      tqWarning("There was an error loading the configuration dialog for this style.");
      return;
   }
   
   void* allocPtr = library->symbol("allocate_tdestyle_config");
   
   if (!allocPtr)
   {
      tqWarning("There was an error loading the configuration dialog for this style.");
      return;
   }
   
	//Create the container dialog
   StyleConfigDialog* dial = new StyleConfigDialog(this, "Baghira Configuration");
   dial->enableButtonSeparator(true);
   
   typedef TQWidget*(* factoryRoutine)( TQWidget* parent );
   
	//Get the factory, and make the widget.
   factoryRoutine factory      = (factoryRoutine)(allocPtr);
   TQWidget*  styleConfig = factory( dial );
   
   TQTabWidget* tw = (TQTabWidget*)styleConfig->child("tabWidget");
   
   TQWidget*  decoConfig = 0;
   TQObject *decoObject = 0;
   if (tw)
   {
      KLibrary* library2 = loader->library( TQFile::encodeName("twin_baghira_config") );
      if (!library2)
      {
         tqWarning("There was an error loading the configuration dialog for the deco.");
         return;
      }
      void* allocPtr2 = library2->symbol("allocate_config");
      if (!allocPtr2)
      {
         tqWarning("There was an error loading the configuration dialog for this style.");
         return;
      }
      typedef TQObject*(* factoryRoutine2)( TDEConfig* conf, TQWidget* parent );
      factoryRoutine2 factory2 = (factoryRoutine2)(allocPtr2);
      decoObject = factory2( 0, tw );
      decoConfig = (TQWidget*)tw->child("ConfigDialog");
      tw->addTab(decoConfig, "Decoration");
   }
   
	//Insert it in...
   dial->setMainWidget( styleConfig );
   
   TQWidget *desktop = TQApplication::desktop();
   TQPoint nPos((desktop->width() - dial->width())/2, (desktop->height() - dial->height() - 100)/2);
   dial->move(nPos);
	//..and connect it to the wrapper
   connect(styleConfig, SIGNAL(changed(bool)), dial, SLOT(setStyleDirty(bool)));
   connect(decoObject, SIGNAL(changed()), dial, SLOT(setDecoDirty()));
   connect(dial, SIGNAL(defaults()), styleConfig, SLOT(defaults()));
   connect(dial, SIGNAL(save()), styleConfig, SLOT(save()));
   connect(dial, SIGNAL(defaults()), decoObject, SLOT(defaults()));
   connect(dial, SIGNAL(save(TDEConfig*)), decoObject, SLOT(save(TDEConfig*)));
   
   if (dial->exec() == TQDialog::Accepted)
   {
      //For now, ask all KDE apps to recreate their styles to apply the setitngs
      if (dial->isStyleDirty())
      {
         KIPC::sendMessageAll(KIPC::StyleChanged);
         KIPC::sendMessageAll(KIPC::ToolbarStyleChanged);
      }
      if (dial->isDecoDirty())
         kapp->dcopClient()->send("twin", "KWinInterface", "reconfigure()", TQByteArray());
   }
   tw->removeChild( decoObject );
   dial->insertChild( decoObject );
   decoConfig->reparent(dial, TQPoint(0,0));
   delete dial;
}

/* overwrite the show event for repositioning the window on top
 of the icon, adapted from kkeyled */
void bab::showEvent(TQShowEvent *e){
    if ( bSwitcher->globalPos->x() >= 0) {
       TQWidget *desktop = TQApplication::desktop();
       int w = desktop->width();
       TQPoint nPos;
       if (bSwitcher->globalPos->y() - height() >= 0 )
       { // it's not on top
          nPos.setY(bSwitcher->globalPos->y() -height());
          nPos.setX(bSwitcher->globalPos->x() - (width() / 2));
       }
       else if ( bSwitcher->globalPos->y() >= 0 )
       {
          nPos.setY(bSwitcher->globalPos->y() + bSwitcher->height() );
          nPos.setX(bSwitcher->globalPos->x() - (width() / 2));
       }
       if ( nPos.x() < 0 )
       {
          nPos.setX(bSwitcher->globalPos->x() + bSwitcher->width());
       }
       else if ( bSwitcher->globalPos->x() + (width() / 2)  > w )
       {
          nPos.setX(bSwitcher->globalPos->x() - width());
       }
       move(nPos);
    }
    
   // If it was set by the normal sessionmanagement it needs
   // to set the Flags again
   setWFlags(TQt::WStyle_StaysOnTop | TQt::WX11BypassWM);
   TQWidget::showEvent(e); // execute the normal showevent
   raise();
}

void bab::saveSettings(){
   TQSettings *config = new TQSettings();
//    TDEConfig *config = new TDEConfig("baghirarc");
   config->beginGroup("/baghira/BAB");
   config->writeEntry("defaultState", DefStyle->currentItem());
   config->writeEntry("roundCorners", cornerCheck->isChecked());
   config->endGroup();
   delete config;
}

TQPoint *BabSwitcher::globalPos = new TQPoint(0,0);

BabSwitcher::BabSwitcher(bab *parent, const char *name) 
                                          : KSystemTray(parent,name), DCOPObject("babInterface") {
   TDEIconLoader* iLoader = TDEGlobal::iconLoader();
   JaguarIcon = iLoader->loadIcon("bab_jaguar", TDEIcon::Small, 22);
   PantherIcon = iLoader->loadIcon("bab_panther", TDEIcon::Small, 22);
   iTunesIcon = iLoader->loadIcon("bab_itunes", TDEIcon::Small, 22);
   TigerIcon = iLoader->loadIcon("bab_tiger", TDEIcon::Small, 22);
   MilkIcon = iLoader->loadIcon("bab_milk", TDEIcon::Small, 22);
   installEventFilter(this);
}

BabSwitcher::~BabSwitcher(){
}

void BabSwitcher::toggle()
{
   if ( state_ < Milk )
      state_++;
   else
      state_ = Jaguar;
   decoState_ = state_;
   TQString nameString;
   switch (state_)
   {
   case Jaguar:
      nameString = "Jaguar";
      break;
   case Panther:
      nameString = "Panther";
      break;
   case iTunes:
      nameString = "Brushed";
      break;
   case Tiger:
      nameString = "Tiger";
      break;
   case Milk:
      nameString = "Milk";
   }
   TQString tmpString = TQDir::homeDirPath() + "/.baghira/" + nameString;
   TQString tmpString2 = TQDir::homeDirPath() + "/.baghira/.bab/.style";
   remove(tmpString2.latin1());
   symlink (tmpString.latin1(), tmpString2.latin1());
   tmpString2 = TQDir::homeDirPath() + "/.baghira/.bab/.deco";
   remove(tmpString2.latin1());
   symlink (tmpString.latin1(), tmpString2.latin1());
   repaint();
}

void BabSwitcher::setStyle(TQString style)
{
   if (style == "Jaguar")
      state_ = Jaguar;
   else if (style == "Brushed")
      state_ = iTunes;
   else if (style == "Tiger")
      state_ = Tiger;
   else if (style == "Milk")
      state_ = Milk;
   else
   {
      if (style != "Panther")
         style = "Panther";
      state_ = Panther;
   }
   TQString tmpString = TQDir::homeDirPath() + "/.baghira/" + style;
   TQString tmpString2 = TQDir::homeDirPath() + "/.baghira/.bab/.style";
   remove(tmpString2.latin1());
   symlink (tmpString.latin1(), tmpString2.latin1());
   repaint();
}

void BabSwitcher::setDeco(TQString deco)
{
   if (deco == "Jaguar")
      decoState_ = Jaguar;
   else if (deco == "Brushed")
      decoState_ = iTunes;
   else if (deco == "Tiger")
      decoState_ = Tiger;
   else if (deco == "Milk")
      decoState_ = Milk;
   else
   {
      if (deco != "Panther")
         deco = "Panther";
      decoState_ = Panther;
   }
   TQString tmpString = TQDir::homeDirPath() + "/.baghira/" + deco;
   TQString tmpString2 = TQDir::homeDirPath() + "/.baghira/.bab/.deco";
   remove(tmpString2.latin1());
   symlink (tmpString.latin1(), tmpString2.latin1());
}

TQString BabSwitcher::style()
{
   switch (state_)
   {
   case Jaguar:
      return "Jaguar";
   default:
   case Panther:
      return "Panther";
   case iTunes:
      return "Brushed";
   case Tiger:
      return "Tiger";
   case Milk:
      return "Milk";
   }
}

TQString BabSwitcher::deco()
{
   switch (decoState_)
   {
   case Jaguar:
      return "Jaguar";
   default:
   case Panther:
      return "Panther";
   case iTunes:
      return "Brushed";
   case Tiger:
      return "Tiger";
   case Milk:
      return "Milk";
   }
}

void BabSwitcher::start(TQString name, TQString settings)
{
   TDEProcess proc;
   TQString section; int i = 0; bool done = false;
   if (name.contains(' '))
   {
      while (!done)
      {
         section = name.section(' ',i,i);
         if (i == 0)
         {
            TQString tmpString = TQDir::homeDirPath() + "/.baghira/" + settings;
            TQString tmpString2 = TQDir::homeDirPath() + "/.baghira/.bab/" + section;
            remove(tmpString2.latin1());
            symlink (tmpString.latin1(), tmpString2.latin1());
         }
         if (!section.isEmpty())
            proc << section;
         else
            done = true;
         i++;
      }
   }
   else
   {
      TQString tmpString = TQDir::homeDirPath() + "/.baghira/" + settings;
      TQString tmpString2 = TQDir::homeDirPath() + "/.baghira/.bab/" + name;
      remove(tmpString2.latin1());
      symlink (tmpString.latin1(), tmpString2.latin1());
      proc << name;
   }
   proc.start(TDEProcess::DontCare);
   proc.detach();
}

void BabSwitcher::emitStyleChanged()
{
   KIPC::sendMessageAll(KIPC::StyleChanged);
   KIPC::sendMessageAll(KIPC::ToolbarStyleChanged);
}

void BabSwitcher::mousePressEvent(TQMouseEvent *e){

  TQWidget *daddy = parentWidget();

  globalPos->setX(e->globalX() - e->x());
  globalPos->setY(e->globalY() - e->y());

   switch ( e->button() ) 
   {
   case LeftButton:
   {
      toggle();
      break;
   }
   case RightButton:
   default:
   {
      if ( daddy->isVisible() )
         daddy->hide();
      else
         daddy->show();
   }
   }
}

void BabSwitcher::paintEvent(TQPaintEvent *ev){
   KSystemTray::paintEvent(ev);
   TQPainter icyApainter(this);
   switch (state_)
   {
   case Jaguar:
      JaguarIcon.isNull() ? icyApainter.fillRect(rect(), TQt::blue) : icyApainter.drawPixmap(0, 0, JaguarIcon);
      break;
   case Panther:
      PantherIcon.isNull() ? icyApainter.fillRect(rect(), TQt::black) : icyApainter.drawPixmap(0, 0, PantherIcon);
      break;
   case iTunes:
      iTunesIcon.isNull() ? icyApainter.fillRect(rect(), TQt::gray) : icyApainter.drawPixmap(0, 0, iTunesIcon);
      break;
   case Tiger:
      TigerIcon.isNull() ? icyApainter.fillRect(rect(), TQt::yellow) : icyApainter.drawPixmap(0, 0, TigerIcon);
      break;
   case Milk:
      MilkIcon.isNull() ? icyApainter.fillRect(rect(), TQt::white) : icyApainter.drawPixmap(0, 0, MilkIcon);
   default:
      break;
   }
   icyApainter.end();
}

Corner::Corner(Side side) : TQWidget(0, (side == left)?"left_corner":"right_corner", TQt::WType_TopLevel | TQt::WStyle_NoBorder | TQt::WStyle_StaysOnTop | TQt::WX11BypassWM )
{
    if (side == left) {
        setFixedSize(5,4);
        move(0,0);
        show();
        setPaletteBackgroundColor(TQt::black);
        XRectangle* xrects = new XRectangle[4];
        xrects[ 0 ].x = 0;
        xrects[ 0 ].y = 0;
        xrects[ 0 ].width = 5;
        xrects[ 0 ].height = 1;
        xrects[ 1 ].x = 0;
        xrects[ 1 ].y = 1;
        xrects[ 1 ].width = 3;
        xrects[ 1 ].height = 1;
        xrects[ 2 ].x = 0;
        xrects[ 2 ].y = 2;
        xrects[ 2 ].width = 2;
        xrects[ 2 ].height = 1;
        xrects[ 3 ].x = 0;
        xrects[ 3 ].y = 3;
        xrects[ 3 ].width = 1;
        xrects[ 3 ].height = 2;
        XShapeCombineRectangles( tqt_xdisplay(), winId(), ShapeBounding, 0, 0,
                                 xrects, 4, ShapeSet, 0 );
        delete[] xrects;
    }
    else {
        setFixedSize(5,4);
        move(TQApplication::desktop()->width()-5,0);
        show();
        setPaletteBackgroundColor(TQt::black);
        XRectangle* xrects = new XRectangle[4];
        xrects[ 0 ].x = 0;
        xrects[ 0 ].y = 0;
        xrects[ 0 ].width = 5;
        xrects[ 0 ].height = 1;
        xrects[ 1 ].x = 2;
        xrects[ 1 ].y = 1;
        xrects[ 1 ].width = 3;
        xrects[ 1 ].height = 1;
        xrects[ 2 ].x = 3;
        xrects[ 2 ].y = 2;
        xrects[ 2 ].width = 2;
        xrects[ 2 ].height = 1;
        xrects[ 3 ].x = 4;
        xrects[ 3 ].y = 3;
        xrects[ 3 ].width = 1;
        xrects[ 3 ].height = 2;
        XShapeCombineRectangles( tqt_xdisplay(), winId(), ShapeBounding, 0, 0,
                                 xrects, 4, ShapeSet, 0 );
        delete[] xrects;
    }
}

void Corner::toggle(bool b)
{
   b?show():hide();
}

#include "bab.moc"
