/****************************************************************************
**
** Copyright (C) 2001-2006 Frank Hemer <frank@hemer.org>,
**                         Tilo Riemer <riemer@crossvc.com>,
**                         Jose Hernandez <joseh@tesco.net>
**
**
**----------------------------------------------------------------------------
**
**----------------------------------------------------------------------------
**
** CrossVC is available under two different licenses:
**
** If CrossVC is linked against the GPLed version of Qt 
** CrossVC is released under the terms of GPL also.
**
** If CrossVC is linked against a nonGPLed version of Qt 
** CrossVC is released under the terms of the 
** CrossVC License for non-Unix platforms (CLNU)
**
**
** CrossVC License for non-Unix platforms (CLNU):
**
** Redistribution and use in binary form, without modification, 
** are permitted provided that the following conditions are met:
**
** 1. Redistributions in binary form must reproduce the above copyright
**    notice, this list of conditions and the following disclaimer in the
**    documentation and/or other materials provided with the distribution.
** 2. It is not permitted to distribute the binary package under a name
**    different than CrossVC.
** 3. The name of the authors may not be used to endorse or promote
**    products derived from this software without specific prior written
**    permission.
** 4. The source code is the creative property of the authors.
**    Extensions and development under the terms of the Gnu Public License
**    are limited to the Unix platform. Any distribution or compilation of 
**    the source code against libraries licensed other than gpl requires 
**    the written permission of the authors.
**
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
**
**
** CrossVC License for Unix platforms:
**
** 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, version 2 of the License.
** 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 version 2 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 "config.h"

#include <qcheckbox.h>
#include <qcombobox.h>
#include <qlineedit.h>
#include <qlistview.h>
#include <qtabwidget.h>
#include <qstring.h>
#include <qmessagebox.h>
#include <qwhatsthis.h>
#include <qpushbutton.h>

#include "PropertiesDialogImpl.h"
#include "ccvscommand.h"
#include "cvslistview.h"
#include "directory.h"
#include "globals.h"


bool PropertiesDialogImpl::m_Recurse = false;
int PropertiesDialogImpl::m_PageIndex = 0;


/**
 * Constructs a PropertiesDialogImpl which is a child of 'parent', with
 * the name 'name' and widget flags set to 'f'
 * The dialog will by default be modeless, unless you set 'modal' to
 * TRUE to construct a modal dialog.
 *
 * @param	parent
 *	Parent widget handle.
 * @param	Item
 *	Subject directory
 */

PropertiesDialogImpl::PropertiesDialogImpl (const QIconSet &whatsThisIconSet,
      QWidget *parent, CvsDirListView * workBench, Directory *Item)
//   : PropertiesDialog (LookAndFeel::g_b0AsParent ? 0 : parent, "Sandbox Properties", true,
   : PropertiesDialog (parent, "Sandbox Properties", true, LookAndFeel::g_modalF),
     m_workBench (workBench), m_Directory (Item), m_pProjectRoot (NULL)
{
   m_pWhatsThis->setIconSet (whatsThisIconSet);
#ifdef Q_WS_MAC
  m_pWhatsThis->setMaximumWidth (m_pWhatsThis->height () * 2);
#else
  m_pWhatsThis->setMaximumWidth (m_pWhatsThis->height ());
#endif

   setCaption (tr ("Sandbox Properties of: ") +
         m_Directory->topDir ()->shortName ());

   m_pCvsRootEdit->setText (Item->getRoot ());

   // Disable sorting
   PropertyList->setSorting (-1);

   m_pRecursive->setChecked (m_Recurse);
   m_pPropertiesTab->setCurrentPage (m_PageIndex);

   refreshDialogData ();
}


void PropertiesDialogImpl::refreshDialogData ()
{
   PropertyList->clear ();

   // Setup
   // Settings List !!Reverse Order!!
   int autoupdate = 0;
   m_pProjectRoot = static_cast <Directory *> (m_Directory->topControlledDir ());
   bool controlled = m_pProjectRoot->isControlled ();
   QString projectName = m_pProjectRoot->relativeName ();
   projectSettings->get (projectName,PAUTOUPDATE,autoupdate);

   m_pCvsRootEdit->setEnabled (controlled);
   m_pRecursive->setEnabled (controlled);

   QStringList AutoUpdatePresetList;
   AutoUpdatePresetList.append (tr ("off"));
   AutoUpdatePresetList.append (tr ("query update"));
   AutoUpdatePresetList.append (tr ("status"));
   AutoUpdatePresetList.append (tr ("update"));
   AutoUpdatePresetList.append (tr ("query update all"));
   AutoUpdatePresetList.append (tr ("update all"));
   AutoUpdateComboBox->clear ();
   AutoUpdateComboBox->insertStringList (AutoUpdatePresetList);

   AutoUpdateComboBox->setCurrentItem (autoupdate);
   AutoUpdateComboBox->setEnabled (controlled);

   QStringList SshPresetList;
   SshPresetList.append (tr ("no ssh"));
   SshPresetList.append (tr ("use ssh"));
   SshPresetList.append (tr ("use own ssh-agent"));
   SshPresetList.append (tr ("use running ssh-agent"));
   m_SshPreset->clear ();
   m_SshPreset->insertStringList (SshPresetList);

   int idx = 0;
   projectSettings->get (projectName,SSHACCESS,idx);
   m_SshPreset->setCurrentItem (idx);

   if (m_Directory->connectMethod ()=="ext") {
      m_SshPreset->setEnabled (true);
   }

   m_CvsServer->setEnabled (controlled);
   QString cvsServerCmd;
   projectSettings->get (projectName,CVSSERVER,cvsServerCmd);
   m_CvsServer->setText (cvsServerCmd);

   if (!cvsServerCmd.isEmpty ()) {
      new QListViewItem (PropertyList, tr ("$CVS_SERVER:"), cvsServerCmd);
   }
   new QListViewItem (PropertyList, tr ("DirTag:"), m_Directory->getDirTag ().mid (1));
   new QListViewItem (PropertyList, tr ("WorkDir:"), m_Directory->fullName ());
   new QListViewItem (PropertyList, tr ("Module root:"), m_pProjectRoot->fullName ());
   new QListViewItem (PropertyList, tr ("auto update:"), AutoUpdatePresetList [autoupdate]);
   new QListViewItem (PropertyList, tr ("Dir Access:"),
         m_Directory->isDisabled () ?
         tr ("disabled") : tr ("enabled"));
   QString proxyString;
   if (m_Directory->connectMethod ().startsWith ("pserver")) {
      proxyString = getProxy (m_Directory->userName ()+"@"+m_Directory->host ());
   }
   if (proxyString.isEmpty ()) proxyString = tr ("No Proxy");
   new QListViewItem (PropertyList, tr ("Proxy:"), proxyString);
   new QListViewItem (PropertyList, tr ("Remote shell:"), QString (idx ? SshPresetList [idx] : QString ("") ) );
   new QListViewItem (PropertyList, tr ("Connection Method:"), m_Directory->connectMethod ());
   new QListViewItem (PropertyList, tr ("Repository:"), m_Directory->rootDir ());
   int port = m_Directory->port ();
   QString sPort = "";
   if (port > -1) sPort = ":" + QString::number (port);
   if (m_Directory->connectMethod ().startsWith ("pserver")) {
      new QListViewItem (PropertyList, tr("Host:"), m_Directory->host () + sPort);
   } else {
      new QListViewItem (PropertyList, tr("Host:"), m_Directory->host ());
   }
   new QListViewItem (PropertyList, tr ("User:"), m_Directory->userName ());
   new QListViewItem (PropertyList, tr ("Module:"), m_Directory->repository ());
}


/**
 * Destroys the object and frees any allocated resources
 */

PropertiesDialogImpl::~PropertiesDialogImpl ()
{
   // no need to delete child widgets, Qt does it all for us
}


void PropertiesDialogImpl::apply ()
{
   m_Recurse = m_pRecursive->isChecked ();
   if (m_Directory->isControlled ()) {

      if (m_Directory->getRoot () != m_pCvsRootEdit->text ()) {

         bool test = FALSE;
         if (m_Recurse) {
            test = m_Directory->hasDisabled ();
         } else {
            test = m_Directory->isDisabled ();
         }

         if (test) {
            QMessageBox::warning (this, tr ("Warning")+", "+tr ("problem detected:"),
                  tr ("There are disabled directories that wouldn't be affected by changing the CVSROOT")+",\n\t"+
                  tr ("aborting"), QMessageBox::Ok, QMessageBox::NoButton);

         } else {

            int res = validateCVSROOT (m_pCvsRootEdit->text ());
            if (res != 0) {
               QMessageBox::warning (this, tr ("Warning")+", "+tr ("problem detected:"),
                     tr ("The given CVSROOT value is invalid")+",\n\t"+
                     tr ("aborting"), QMessageBox::Ok, QMessageBox::NoButton);

            } else {

               /* Assemble a ChRoot (change CVSROOT) command and dispatch it
                * to the target module.  The target module will then call the
                * command with passing a reference to itself as an argument.
                */
               CCvsCommandChRoot *ChRoot =
                  new CCvsCommandChRoot (m_pCvsRootEdit->text (), m_Recurse);

               m_Directory->execute (*ChRoot);
               if (ChRoot->needRereadTree ()) {
                  QString name = m_Directory->fullName ();
                  emit rereadTree ();
                  //rereadTree deletes m_Directory so this must be reassigned too
                  m_Directory = static_cast <Directory *> (m_workBench->selectedItem ());
                  assert (m_Directory);
                  assert (m_Directory->fullName () == name);
                  refreshDialogData ();
               }

               /* TODO: instead of deleting it, place the command in a global
                * command stack so that it can be undone at the user's request.
                */
               delete ChRoot;
            }
         }
      }

      QString projectName = m_pProjectRoot->relativeName ();

      //auto update
      int autoupdate = AutoUpdateComboBox->currentItem ();
      projectSettings->set (projectName,PAUTOUPDATE,autoupdate);

      if (m_pProjectRoot != m_Directory->topDir ()) {
         m_pProjectRoot->setAutoUpdate (AUTOUPDATE && (autoupdate != AutoUpdate::OFF));
      }

      int ssh = -1;
      //ssh access
      switch ( m_SshPreset->currentItem ()) {
         case 0: {
            ssh = NOSSH;
            break;
         }
         case 1: {
            ssh = USESSH;
            break;
         }
         case 2: {
            ssh = USESSHAGENT;
            break;
         }
         case 3: {
            ssh = USESSHAGENTVARS;
            break;
         }
         default:;
      }
      projectSettings->set (projectName,SSHACCESS,ssh);

      QString cvsServerCmd = m_CvsServer->text ();
      projectSettings->set (projectName,CVSSERVER,cvsServerCmd);
   }
   refreshDialogData ();
}


void PropertiesDialogImpl::accept ()
{
   m_PageIndex = m_pPropertiesTab->currentPageIndex ();

   apply ();
   PropertiesDialog::accept ();
}


void PropertiesDialogImpl::enterWhatsThisMode ()
{
   QWhatsThis::enterWhatsThisMode ();
}

