/*
    This file is part of the KDE Project

    Copyright (C) 2003, 2004 Mickael Marchand <marchand@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    This software 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 library; see the file COPYING. If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include <tdeapplication.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <tdemessagebox.h>
#include <tdefiledialog.h>
#include <ktextedit.h>
#include <kpassdlg.h>
#include <tqdir.h>
#include <tqfile.h>

#include "config.h"

#include "kdevsvnd.h"

#include "kdevsvnd_widgets.h"
#include "commitdlg.h"

extern "C" {
    KDE_EXPORT KDEDModule *create_kdevsvnd(const TQCString &name) {
       return new KDevSvnd(name);
    }
}

KDevSvnd::KDevSvnd(const TQCString &name)
 : KDEDModule(name) {
}
KDevSvnd::~KDevSvnd()
{}

TQString KDevSvnd::commitDialog(TQString modifiedFiles) {
	CommitDlg commitDlg;
	commitDlg.setCaption(i18n("Enter Commit Log Message:"));
	commitDlg.listMessage->setText( modifiedFiles );
	int result = commitDlg.exec();
	if ( result == TQDialog::Accepted ) {
		return commitDlg.textMessage->text();
	} else
		return TQString();
}
int KDevSvnd::sslServerTrustPrompt( TQString errmsg, TQString hostname, TQString fingerPrint, TQString validfrom, TQString validuntil, TQString issuerName, TQString ascii_cert )
{
	SvnSSLTrustPrompt dlg;
	dlg.setupCertInfo( hostname, fingerPrint, validfrom, validuntil, issuerName, ascii_cert );
	dlg.setupFailedReasonMsg( errmsg );
	int result = dlg.exec();
	if ( result == TQDialog::Accepted ){
		return dlg.code();
	} else{
		return -1;
	}
}
TQString KDevSvnd::sslCertFile()
{
	TQString fileName = KFileDialog::getOpenFileName(TQString(),TQString(),0, i18n("Open SSL certificate file"));
	return fileName;
}

TQString KDevSvnd::sslPasswdDlg(TQString promptMsg)
{
	TQString passwd;
	int ret = KPasswordDialog::getPassword( passwd,promptMsg );
	if( ret == KPasswordDialog::Accepted ){
		TQString retstr;
		retstr.setNum(1);
		return retstr + passwd;
	} else{
		TQString nullstr;
		nullstr.setNum(-1);
		return nullstr;
	}
}


// void KDevSvnd::registerMe(const TQCString &app)
// {
// 	insert(app, "test", new TestObject(app));
//    // When 'app' unregisters with DCOP, the TestObject will get deleted.
// }

// bool KSvnd::AreAnyFilesInSvn( const KURL::List& wclist ) {
// 	for ( TQValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
// 		kdDebug( 9036 ) << "Checking file " << ( *it ) << endl;
// 		TQDir bdir ( ( *it ).path() );
// 		if ( bdir.exists() && TQFile::exists( ( *it ).path() + "/.svn/entries" ) ) {
// 			return true;
// 		} else if ( !bdir.exists() ) {
// 			if ( isFileInSvnEntries( ( *it ).fileName(), ( *it ).directory() + "/.svn/entries" ) || isFileInExternals ( ( *it ).fileName(), ( *it ).directory()+"/.svn/dir-props" ) )
// 				return true;
// 		}
// 	}
// 	return false;
// }
//
// bool KSvnd::AreAnyFilesNotInSvn( const KURL::List& wclist ) {
// 	for ( TQValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
// 		kdDebug( 9036 ) << "Checking file " << ( *it ) << endl;
// 		TQDir bdir ( ( *it ).path() );
// 		if ( bdir.exists() && !TQFile::exists( ( *it ).path() + "/.svn/entries" ) ) {
// 			return true;
// 		} else if ( !bdir.exists() ) {
// 			if ( !isFileInSvnEntries( ( *it ).fileName(),( *it ).directory() + "/.svn/entries" ) && !isFileInExternals ( ( *it ).fileName(), ( *it ).directory()+"/.svn/dir-props" ) )
// 				return true;
// 		}
// 	}
// 	return false;
// }
//
// bool KSvnd::AreAllFilesInSvn( const KURL::List& wclist ) {
// 	for ( TQValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
// 		kdDebug( 9036 ) << "Checking file " << ( *it ) << endl;
// 		TQDir bdir ( ( *it ).path() );
// 		if ( bdir.exists() && !TQFile::exists( ( *it ).path() + "/.svn/entries" ) ) {
// 			return false;
// 		} else if ( !bdir.exists() ) {
// 			if ( !isFileInSvnEntries( ( *it ).fileName(),( *it ).directory() + "/.svn/entries" ) && !isFileInExternals ( ( *it ).fileName(), ( *it ).directory()+"/.svn/dir-props" )  )
// 				return false;
// 		}
// 	}
// 	return true;
// }
//
// bool KSvnd::AreAllFilesNotInSvn( const KURL::List& wclist ) {
// 	for ( TQValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
// 		kdDebug( 9036 ) << "Checking file " << ( *it ) << endl;
// 		TQDir bdir ( ( *it ).path() );
// 		if ( bdir.exists() && TQFile::exists( ( *it ).path() + "/.svn/entries" ) ) {
// 			return false;
// 		} else if ( !bdir.exists() ) {
// 			if ( isFileInSvnEntries( ( *it ).fileName(),( *it ).directory() + "/.svn/entries" ) || isFileInExternals ( ( *it ).fileName(), ( *it ).directory()+"/.svn/dir-props" ) )
// 				return false;
// 		}
// 	}
// 	return true;
// }
//
// bool KSvnd::isFileInSvnEntries ( const TQString filename, const TQString entfile ) {
// 	TQFile file( entfile );
// 	if ( file.open( IO_ReadOnly ) ) {
// 		TQTextStream stream( &file );
// 		TQString line;
// 		while ( !stream.atEnd() ) {
// 			line = stream.readLine().simplifyWhiteSpace();
// 			if ( line == "name=\""+ filename + "\"" ) {
// 				file.close();
// 				return true;
// 			}
// 		}
// 		file.close();
// 	}
// 	return false;
// }
//
// bool KSvnd::isFileInExternals ( const TQString filename, const TQString propfile ) {
// 	TQFile file( propfile );
// 	if ( file.open( IO_ReadOnly ) ) {
// 		TQTextStream stream( &file );
// 		TQStringList line;
// 		while ( !stream.atEnd() )
// 			line << stream.readLine().simplifyWhiteSpace();
// 		for ( uint i = 0 ; i < line.count(); i++ ) {
// 			if ( line[ i ] == "K 13"  && line[ i+1 ] == "svn:externals" ) { //Key 13 : svn:externals
// 				//next line should be "V xx"
// 				if ( line [ i+2 ].startsWith( "V " ) ) {
// 					//ok browse the values now
// 					i+=2;
// 					while ( i < line.count() ) {
// 						if ( line[ i ].startsWith( filename+" " ) ) { //found it !
// 							file.close( );
// 							return true;
// 						} else if ( line[ i ].isEmpty() ) {
// 							file.close( );
// 							return false; //we are out of svn:externals now...
// 						}
// 						i++;
// 					}
// 				}
// 			}
// 		}
// 		file.close();
// 	}
// 	return false;
// }
//
// bool KSvnd::anyNotValidWorkingCopy( const KURL::List& wclist ) {
// 	bool result = true; //one negative match is enough
// 	for ( TQValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
// 		//exception for .svn dirs
// 		if ( ( *it ).path(-1).endsWith( "/.svn" ) )
// 			return true;
// 		//if is a directory check whether it contains a .svn/entries file
// 		TQDir dir( ( *it ).path() );
// 		if ( dir.exists() ) { //it's a dir
// 			if ( !TQFile::exists( ( *it ).path() + "/.svn/entries" ) )
// 				result = false;
// 		}
//
// 		//else check if ./.svn/entries exists
// 		if ( !TQFile::exists( ( *it ).directory() + "/.svn/entries" ) )
// 			result = false;
// 	}
// 	return result;
// }
//
// bool KSvnd::anyValidWorkingCopy( const KURL::List& wclist ) {
// 	for ( TQValueListConstIterator<KURL> it = wclist.begin(); it != wclist.end() ; ++it ) {
// 		//skip .svn dirs
// 		if ( ( *it ).path(-1).endsWith( "/.svn" ) )
// 			continue;
// 		//if is a directory check whether it contains a .svn/entries file
// 		TQDir dir( ( *it ).path() );
// 		if ( dir.exists() ) { //it's a dir
// 			if ( TQFile::exists( ( *it ).path() + "/.svn/entries" ) )
// 				return true;
// 		}
//
// 		//else check if ./.svn/entries exists
// 		if ( TQFile::exists( ( *it ).directory() + "/.svn/entries" ) )
// 			return true;
// 	}
// 	return false;
// }
//
// int KSvnd::getStatus( const KURL::List& list ) {
// 	int result = 0;
// 	uint files = 0, folders = 0, parentsentries = 0, parentshavesvn = 0, subdirhavesvn = 0, external = 0;
// 	for ( TQValueListConstIterator<KURL> it = list.begin(); it != list.end() ; ++it ) {
// 		if ( isFolder ( ( *it ) ) ) {
// 			folders++;
// 		} else {
// 			files++;
// 		}
// 		if ( isFileInSvnEntries ( (*it).filename(),( *it ).directory() + "/.svn/entries" ) ) { // normal subdir known in the working copy
// 			parentsentries++;
// 		} else if ( isFolder( *it ) ) { // other subfolders (either another module checkouted or an external, or something not known at all)
// 			if ( TQFile::exists( ( *it ).path() + "/.svn/entries" ) )
// 				subdirhavesvn++;
// 			if ( isFileInExternals( (*it).filename(), ( *it ).directory() + "/.svn/dir-props" ) ) {
// 				external++;
// 			}
// 		}
// 		if ( ( isFolder( ( *it ) ) && TQFile::exists( ( *it ).directory() + "../.svn/entries" ) ) || TQFile::exists( ( *it ).directory() + "/.svn/entries" ) ) //parent has a .svn ?
// 			parentshavesvn++;
// 	}
// 	if ( files > 0 )
// 		result |= SomeAreFiles;
// 	if ( folders == list.count() ) {
// 		result |= AllAreFolders;
// 		result |= SomeAreFolders;
// 	}
// 	if ( folders > 0 )
// 		result |= SomeAreFolders;
// 	if ( parentsentries == list.count() ) {
// 		result |= AllAreInParentsEntries;
// 		result |= SomeAreInParentsEntries;
// 	} else if ( parentsentries != 0 )
// 		result |= SomeAreInParentsEntries;
// 	if ( parentshavesvn == list.count() ) {
// 		result |= AllParentsHaveSvn;
// 		result |= SomeParentsHaveSvn;
// 	} else if ( parentshavesvn > 0 )
// 		result |= SomeParentsHaveSvn;
// 	if ( subdirhavesvn == list.count() ) {
// 		result |= AllHaveSvn;
// 		result |= SomeHaveSvn;
// 	} else if ( subdirhavesvn > 0 )
// 		result |= SomeHaveSvn;
// 	if ( external == list.count() ) {
// 		result |= AllAreExternalToParent;
// 		result |= SomeAreExternalToParent;
// 	} else if ( external > 0 )
// 		result |= SomeAreExternalToParent;
//
// 	return result;
// }
//
// bool KSvnd::isFolder( const KURL& url ) {
// 	TQDir d( url.path() );
// 	return d.exists();
// }
//
// TQStringList KSvnd::getActionMenu ( const KURL::List &list ) {
// 	TQStringList result;
// 	int listStatus = getStatus( list );
//
// 	if ( !(listStatus & SomeAreInParentsEntries) &&
// 	     !(listStatus & SomeAreExternalToParent) &&
// 	     !(listStatus & SomeHaveSvn)) {
// 		if( list.size() == 1 && listStatus & SomeAreFolders) {
// 			result << "Checkout";
// 			result << "Export";
// //			result << "CreateRepository";
// 			result << "Import";
// 		}
// 	} else if ( (listStatus & AllAreInParentsEntries) ) {
// 		result << "Diff";
// 		//In SVN
// //		result << "ShowLog";
// //		result << "CheckForModifications";
// //		result << "RevisionGraph";
// //		result << "_SEPARATOR_";
// //		result << "Update to revision..."
// 		result << "Rename";
// 		result << "Delete";
// 		if( listStatus & SomeAreFolders && !(listStatus & SomeAreFiles)) {
// 			result << "Revert";
// //			result << "Cleanup";
// 		}
// 		result << "_SEPARATOR_";
// //		result << "BranchTag";
// 		result << "Switch";
// 		result << "Merge";
// 		if( listStatus & SomeAreFolders && !(listStatus & SomeAreFiles)) {
// //			result << "Export";
// //			result << "Relocate";
// 			result << "_SEPARATOR_";
// 			result << "Add";
// 		}
// 		result << "_SEPARATOR_";
// 		if( listStatus & SomeAreFiles && !(listStatus & SomeAreFolders)) {
// 			result << "Blame";
// 		}
// 		result << "CreatePatch";
//
// 		if( list.size() == 1 && listStatus & SomeAreFolders) {
// //			result << "ApplyPatchToFolder";
// 		}
// 	}
// 	return result;
// }
//
// TQStringList KSvnd::getTopLevelActionMenu ( const KURL::List &list ) {
// 	TQStringList result;
// 	int listStatus = getStatus( list );
//
//
// 	if ( ( listStatus & AllParentsHaveSvn &&
// 			( ( listStatus & SomeAreExternalToParent ) || ( listStatus & SomeAreInParentsEntries ) )
// 				|| ( listStatus & SomeHaveSvn ) )
// 		) {
// 		result << "Update";
// 		result << "Commit";
// 	}
//
// 	return result;
// }
//
// #if 0
// void KSvnd::notify(const TQString& path, int action, int kind, const TQString& mime_type, int content_state, int prop_state, long int revision, const TQString& userstring) {
// 	kdDebug(9036) << "KDED/Subversion : notify " << path << " action : " << action << " mime_type : " << mime_type << " content_state : " << content_state << " prop_state : " << prop_state << " revision : " << revision << " userstring : " << userstring << endl;
// 	TQByteArray params;
//
// 	TQDataStream stream(params, IO_WriteOnly);
// 	stream << path << action << kind << mime_type << content_state << prop_state << revision << userstring;
//
// 	emitDCOPSignal( "subversionNotify(TQString,int,int,TQString,int,int,long int,TQString)", params );
// }
//
// void KSvnd::status(const TQString& path, int text_status, int prop_status, int repos_text_status, int repos_prop_status, long int rev ) {
// 	kdDebug(9036) << "KDED/Subversion : status " << path << " " << text_status << " " << prop_status << " "
// 			<< repos_text_status << " " << repos_prop_status << " " << rev << endl;
// 	TQByteArray params;
//
// 	TQDataStream stream(params, IO_WriteOnly);
// 	stream << path << text_status << prop_status << repos_text_status << repos_prop_status << rev;
//
// 	emitDCOPSignal( "subversionStatus(TQString,int,int,int,int,long int)", params );
// }
//
// void KSvnd::popupMessage( const TQString& message ) {
// 	kdDebug(9036) << "KDED/Subversion : popupMessage" << message << endl;
// 	KMessageBox::information(0, message, i18n( "Subversion" ) );
// }
// #endif

#include "kdevsvnd.moc"
