/***************************************************************************
 *   Copyright (C) 2001 by Bernd Gehrmann                                  *
 *   bernd@kdevelop.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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "subprojectoptionsdlg.h"

#include <tqdom.h>
#include <tqheader.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqlineedit.h>
#include <tqpushbutton.h>
#include <tqcheckbox.h>
#include <tqregexp.h>
#include <kbuttonbox.h>
#include <kdebug.h>
#include <kdialog.h>
#include <keditlistbox.h>
#include <kinputdialog.h>
#include <klocale.h>
#include <knotifyclient.h>
#include <kservice.h>
#include <kurlrequesterdlg.h>
#include <kurlrequester.h>
#include <kurlcompletion.h>
#include <kfiledialog.h>
#include "domutil.h"
#include "misc.h"
#include "addprefixdlg.h"

#include "autolistviewitems.h"

#include "autoprojectpart.h"
#include "autoprojectwidget.h"


SubprojectOptionsDialog::SubprojectOptionsDialog(AutoProjectPart *part, AutoProjectWidget *widget,
                                                 SubprojectItem *item, TQWidget *parent, const char *name)
    : SubprojectOptionsDialogBase(parent, name, true)
{
    setCaption(i18n("Subproject Options for '%1'").arg(item->subdir));

    subProject = item;
    m_part = part;

    TQFontMetrics fm(cflags_edit->fontMetrics());
    int wid = fm.width('X')*35;
    cflags_edit->setMinimumWidth(wid);
    cxxflags_edit->setMinimumWidth(wid);
    fflags_edit->setMinimumWidth(wid);

    TQDomDocument &dom = *part->projectDom();
    TQString prefix = "/kdevautoproject/configurations/" + m_part->currentBuildConfig() + "/";

    ccompiler = DomUtil::readEntry(dom, prefix + "ccompiler", "kdevgccoptions");
    cxxcompiler = DomUtil::readEntry(dom, prefix + "cxxcompiler", "kdevgppoptions");
    f77compiler = DomUtil::readEntry(dom, prefix + "f77compiler", "kdevg77options");

    if (!KService::serviceByDesktopName(ccompiler))
        cflags_button->setEnabled(false);
    if (!KService::serviceByDesktopName(cxxcompiler))
        cxxflags_button->setEnabled(false);
    if (!KService::serviceByDesktopName(f77compiler))
        fflags_button->setEnabled(false);

    insideinc_listview->header()->hide();
    outsideinc_listview->header()->hide();
    buildorder_listview->header()->hide();

    insideinc_listview->setSorting(-1);
    outsideinc_listview->setSorting(-1);
    prefix_listview->setSorting(-1);
    buildorder_listview->setSorting(-1);

    connect( prefix_listview, TQT_SIGNAL( doubleClicked ( TQListViewItem *, const TQPoint &, int ) ), this, TQT_SLOT( editPrefixClicked() ) );

    // Insert all subdirectories as possible include directories
    TQStringList l = widget->allSubprojects();
    TQCheckListItem *lastItem = 0;
    TQStringList::ConstIterator it;
    for (it = l.begin(); it != l.end(); ++it) {
    kdDebug(9020) << "----------> subproject = " << (*it) << endl;
	TQString subProjectName = *it;

	if( subProjectName.isEmpty() ){
	    subProjectName = TQString::fromLatin1( "." );
	}
        TQCheckListItem *clitem = new TQCheckListItem(insideinc_listview, subProjectName, TQCheckListItem::CheckBox);
        if (lastItem)
            clitem->moveItem(lastItem);
        lastItem = clitem;
    }

    setIcon ( SmallIcon ( "configure" ) );

    readConfig();
}


SubprojectOptionsDialog::~SubprojectOptionsDialog()
{}


void SubprojectOptionsDialog::readConfig()
{

    cflags_edit->setText(subProject->variables["AM_CFLAGS"]);
    cxxflags_edit->setText(subProject->variables["AM_CXXFLAGS"]);
    fflags_edit->setText(subProject->variables["AM_FFLAGS"]);

    metasources_checkbox->setChecked(subProject->variables["METASOURCES"].stripWhiteSpace() == "AUTO");

    TQString includes = subProject->variables["INCLUDES"];
    TQStringList includeslist = TQStringList::split(TQRegExp("[ \t]"), TQString(includes));

    TQListViewItem *lastItem = 0;
    TQStringList::Iterator it;
    for (it = includeslist.begin(); it != includeslist.end(); ++it) {
        TQCheckListItem *clitem = static_cast<TQCheckListItem*>(insideinc_listview->firstChild());
        while (clitem) {
            if (*it == ("-I$(top_srcdir)/" + clitem->text())) {
                clitem->setOn(true);
                break;
            }
            clitem = static_cast<TQCheckListItem*>(clitem->nextSibling());
        }
        if (!clitem) {
            TQListViewItem *item = new TQListViewItem(outsideinc_listview, *it);
            if (lastItem)
                item->moveItem(lastItem);
            lastItem = item;
        }
    }

    TQMap<TQString, TQString>::ConstIterator it2;
    for (it2 = subProject->prefixes.begin(); it2 != subProject->prefixes.end(); ++it2)
        new TQListViewItem(prefix_listview, it2.key(), it2.data());

    TQString subdirs = subProject->variables["SUBDIRS"];
    kdDebug(9020) << "Subdirs variable: " << subdirs << endl;
    TQStringList subdirslist = TQStringList::split(TQRegExp("[ \t]"), TQString(subdirs));
    lastItem = 0;
    for (it = subdirslist.begin(); it != subdirslist.end(); ++it) {
        TQListViewItem *item = new TQListViewItem(buildorder_listview, *it);
        if (lastItem)
            item->moveItem(lastItem);
        lastItem = item;
    }
}


void SubprojectOptionsDialog::storeConfig()
{
    TQMap<TQString, TQString> replaceMap;

    TQString old_cflags = subProject->variables["AM_CFLAGS"];
    TQString new_cflags = cflags_edit->text();
    if (new_cflags != old_cflags) {
        subProject->variables["AM_CFLAGS"] = new_cflags;
        replaceMap.insert("AM_CFLAGS", new_cflags);
    }

    TQString old_cxxflags = subProject->variables["AM_CXXFLAGS"];
    TQString new_cxxflags = cxxflags_edit->text();
    if (new_cxxflags != old_cxxflags) {
        subProject->variables["AM_CXXFLAGS"] = new_cxxflags;
        replaceMap.insert("AM_CXXFLAGS", new_cxxflags);
    }

    TQString old_fflags = subProject->variables["AM_FFLAGS"];
    TQString new_fflags = fflags_edit->text();
    if (new_fflags != old_fflags) {
        subProject->variables["AM_FFLAGS"] = new_fflags;
        replaceMap.insert("AM_FFLAGS", new_fflags);
    }

    TQString old_metasources = subProject->variables["METASOURCES"];
    TQString new_metasources = metasources_checkbox->isChecked() ? TQString::fromLatin1("AUTO") : TQString::null;
    if (new_metasources != old_metasources) {
        subProject->variables["METASOURCES"] = new_metasources;
        replaceMap.insert("METASOURCES", new_metasources);
    }

    TQStringList includeslist;
    TQCheckListItem *clitem = static_cast<TQCheckListItem*>(insideinc_listview->firstChild());
    while (clitem) {
        if (clitem->isOn())
            includeslist.append("-I$(top_srcdir)/" + clitem->text());
        clitem = static_cast<TQCheckListItem*>(clitem->nextSibling());
    }
    clitem = static_cast<TQCheckListItem*>(outsideinc_listview->firstChild());
    while (clitem) {
        includeslist.append(clitem->text());
        clitem = static_cast<TQCheckListItem*>(clitem->nextSibling());
    }
    TQString includes = includeslist.join(" ");
    subProject->variables["INCLUDES"] = includes;
    replaceMap.insert("INCLUDES", includes);

    subProject->prefixes.clear();
    for (TQListViewItem *item = prefix_listview->firstChild();
         item; item = item->nextSibling()) {
        TQString key = item->text(0);
        TQString data = item->text(1);
        subProject->prefixes[key] = data;
        replaceMap.insert(key + "dir", data);
    }
    /// \FIXME take removed prefixes into account

    TQStringList subdirslist;
    for (TQListViewItem *item = buildorder_listview->firstChild();
         item; item = item->nextSibling())
        subdirslist.append(item->text(0));
    TQString subdirs = subdirslist.join(" ");
    kdDebug() << "New subdirs variable: " << subdirs << endl;
    subProject->variables["SUBDIRS"] = subdirs;
    replaceMap.insert("SUBDIRS", subdirs);

    AutoProjectTool::setMakefileam(subProject->path + "/Makefile.am", replaceMap);
}


void SubprojectOptionsDialog::cflagsClicked()
{
    TQString new_cflags = AutoProjectTool::execFlagsDialog(ccompiler, cflags_edit->text(), this);
//    if (!new_cflags.isNull())
        cflags_edit->setText(new_cflags);
}


void SubprojectOptionsDialog::cxxFlagsClicked()
{
    TQString new_cxxflags = AutoProjectTool::execFlagsDialog(cxxcompiler, cxxflags_edit->text(), this);
//    if (!new_cxxflags.isNull())
        cxxflags_edit->setText(new_cxxflags);
}


void SubprojectOptionsDialog::fflagsClicked()
{
    TQString new_fflags = AutoProjectTool::execFlagsDialog(f77compiler, fflags_edit->text(), this);
//    if (!new_fflags.isNull())
        fflags_edit->setText(new_fflags);
}


void SubprojectOptionsDialog::insideMoveUpClicked()
{
    if (insideinc_listview->currentItem() == insideinc_listview->firstChild()) {
        KNotifyClient::beep();
        return;
    }

    TQListViewItem *item = insideinc_listview->firstChild();
    while (item->nextSibling() != insideinc_listview->currentItem())
        item = item->nextSibling();
    item->moveItem(insideinc_listview->currentItem());
}


void SubprojectOptionsDialog::insideMoveDownClicked()
{
   if (insideinc_listview->currentItem() == 0 || insideinc_listview->currentItem()->nextSibling() == 0) {
        KNotifyClient::beep();
        return;
   }

   insideinc_listview->currentItem()->moveItem(insideinc_listview->currentItem()->nextSibling());
}


void SubprojectOptionsDialog::outsideMoveUpClicked()
{
    if (outsideinc_listview->currentItem() == outsideinc_listview->firstChild()) {
        KNotifyClient::beep();
        return;
    }

    TQListViewItem *item = outsideinc_listview->firstChild();
    while (item->nextSibling() != outsideinc_listview->currentItem())
        item = item->nextSibling();
    item->moveItem(outsideinc_listview->currentItem());
}


void SubprojectOptionsDialog::outsideMoveDownClicked()
{
   if (outsideinc_listview->currentItem() == 0 || outsideinc_listview->currentItem()->nextSibling() == 0) {
        KNotifyClient::beep();
        return;
   }

   outsideinc_listview->currentItem()->moveItem(outsideinc_listview->currentItem()->nextSibling());
}

void SubprojectOptionsDialog::outsideAddClicked()
{
    KURLRequesterDlg dialog( "", i18n( "Add Include directory: Choose directory, give -Idirectory or use a variable with -I$(FOOBAR)" ), 0, 0 );
    dialog.urlRequester() ->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly );
    dialog.urlRequester() ->setURL( TQString::null );
    if ( dialog.exec() != TQDialog::Accepted )
        return ;
    TQString file = dialog.urlRequester() ->url();
    if ( !file.isEmpty() )
    {
        if ( !file.isEmpty() )
        {
            if( file.startsWith("-I") )
                new TQListViewItem( outsideinc_listview, file );
            else
            {
                new TQListViewItem( outsideinc_listview, "-I"+file );
            }
        }
    }
}


void SubprojectOptionsDialog::outsideEditClicked()
{
    if ( (outsideinc_listview->childCount()==0) || (outsideinc_listview->currentItem() == 0) )
        return;
    bool ok;
    TQString dir = KInputDialog::getText(i18n("Edit Include Directory"), i18n("Edit include directory:"),
            outsideinc_listview->currentItem()-> text(0), &ok, 0);
    if (ok && !dir.isEmpty())
        outsideinc_listview->currentItem()-> setText(0, dir);
}


void SubprojectOptionsDialog::outsideRemoveClicked()
{
    delete outsideinc_listview->currentItem();
}


void SubprojectOptionsDialog::addPrefixClicked()
{
    AddPrefixDialog dlg;
    if (!dlg.exec() || dlg.name().isEmpty() || dlg.path().isEmpty() )
        return;

    new TQListViewItem(prefix_listview, dlg.name(), dlg.path());
}


void SubprojectOptionsDialog::editPrefixClicked()
{
    TQListViewItem* lvItem = prefix_listview->currentItem();
    if ( (prefix_listview->childCount()==0) || (lvItem == 0) )
        return;
    AddPrefixDialog dlg(lvItem-> text(0), lvItem-> text(1));
    dlg.setCaption(i18n("Edit Prefix"));
    if (!dlg.exec() || dlg.name().isEmpty() || dlg.path().isEmpty() )
        return;
   lvItem-> setText(0, dlg.name());
   lvItem-> setText(1, dlg.path());
}

void SubprojectOptionsDialog::removePrefixClicked()
{
    delete prefix_listview->currentItem();
}


void SubprojectOptionsDialog::buildorderMoveUpClicked()
{
    if (buildorder_listview->currentItem() == buildorder_listview->firstChild()) {
        KNotifyClient::beep();
        return;
    }

    TQListViewItem *item = buildorder_listview->firstChild();
    while (item->nextSibling() != buildorder_listview->currentItem())
        item = item->nextSibling();
    item->moveItem(buildorder_listview->currentItem());
}


void SubprojectOptionsDialog::buildorderMoveDownClicked()
{
   if (buildorder_listview->currentItem() == 0 || buildorder_listview->currentItem()->nextSibling() == 0) {
        KNotifyClient::beep();
        return;
   }

   buildorder_listview->currentItem()->moveItem(buildorder_listview->currentItem()->nextSibling());
}


void SubprojectOptionsDialog::accept()
{
    storeConfig();
    TQDialog::accept();
}

#include "subprojectoptionsdlg.moc"