/* Copyright (C) 2002 Philippe Fremy <pfremy@kde.org>
	 Mickael Marchand <marchand@kde.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.

	 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; see the file COPYING.  If not, write to
	 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
	 Boston, MA 02111-1307, USA.
	 */


#include "vimwidget.h"
#include "vimdocument.h"
#include "vimview.h"
#include "vimpart_factory.h"

#include <kapplication.h>
#include <kdebug.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <qlayout.h>
#include <kstdaction.h>
#include <kaction.h>

#include <keditcl.h>
#include <iostream>

using namespace std;

namespace Vim 
{
	View::View( Document *doc, QWidget *parent, const char *name ) : KTextEditor::View (doc, parent, name)
	{
		//keep it first, it's long to start, so we'll setup here while it's starting
		_vimWidget = new VimWidget ( this, name );
		setInstance ( VimPartFactory::instance() );
		m_doc=doc;
		setFocusPolicy(StrongFocus);	
		QVBoxLayout *v = new QVBoxLayout(this);
		v->add(_vimWidget);

		_vimWidget->show();

		if (!doc->m_singleView) {
			kdDebug(90000) << "not single view" << endl;
			setXMLFile( "vimpartui.rc" );
		} else {
			if( doc->m_browserView) {
				kdDebug(90000) << "loading vimpartuibrowser" << endl;
				setXMLFile( "vimpartuibrowser.rc" );
			} else if (doc->m_readOnly) {
				kdDebug(90000) << "loading vimpartuireadonly" << endl;
				setXMLFile( "vimpartuireadonly.rc" );
			} else {
				kdDebug(90000) << "loading vimpartui" << endl;
				setXMLFile( "vimpartui.rc" );
			}
		}
		setupActions();
	}

	View::~View()
	{
		kdDebug(90000) << "View destructor" << endl;
		delete _vimWidget;
	}

	KTextEditor::Document *View::document() const
	{
		return m_doc;
	}

	QPoint View::cursorCoordinates()
	{
		//possible with vim ? hmmm
		return QPoint(0,0);
	}

	void View::cursorPosition(uint *line, uint *col)
	{
		*line=cursorLine();
		*col=cursorColumn();
	}

	void View::cursorPositionReal (uint *line, uint *col)
	{
		*line=cursorLine();
		*col=cursorColumn();
	}

	bool View::setCursorPosition (uint line, uint col)
	{
		line++;col++;
		_vimWidget->sendCmdLineCmd(QString("call cursor(%1,%2)").arg((int)line).arg((int)col));
		_vimWidget->sendNormalCmd("zz");
		return true;
	}
	
	bool View::setCursorPositionReal (uint line, uint col)
	{
		return setCursorPosition(line,col);
	}

	uint View::cursorLine ()
	{
		QString t = _vimWidget->evalExpr("winline()");
		return t.toUInt()-1;
	}

	uint View::cursorColumn()
	{
		QString t = _vimWidget->evalExpr("wincol()");
		return t.toUInt()-1;
	}

	uint View::cursorColumnReal()
	{
		return cursorColumn();	
	}

	void View::setupActions()
	{
		KActionCollection *ac = actionCollection();
		KAction *a;

		if (!m_doc->m_readOnly)
		{
			a=KStdAction::save(this, SLOT(save()), ac);
			a->setWhatsThis(i18n("Save the current document"));
			a->setShortcutText("");

			a=KStdAction::undo(this, SLOT(undo()), ac);
			a->setWhatsThis(i18n("Revert the most recent editing actions"));
			a->setShortcutText("");

			a=KStdAction::redo(this, SLOT(redo()), ac);
			a->setWhatsThis(i18n("Revert the most recent undo operation"));
			a->setShortcutText("");

			a=KStdAction::cut(this, SLOT(cut()), ac);
			a->setWhatsThis(i18n("Cut the selected text and move it to the clipboard"));
			a->setShortcutText("");

			a=KStdAction::paste(this, SLOT(paste()), ac);
			a->setWhatsThis(i18n("Paste previously copied or cut clipboard contents"));
			a->setShortcutText("");
		}

		a=KStdAction::close(this, SLOT(close()), ac);
		a->setWhatsThis(i18n( "Closes the current document."));
		a->setShortcutText("");

		a=KStdAction::copy(this, SLOT(copy()), ac);
		a->setWhatsThis(i18n( "Use this command to copy the currently selected text to the system clipboard."));
		a->setShortcutText("");

		a=KStdAction::saveAs(this, SLOT(saveAs()), ac);
		a->setWhatsThis(i18n("Save the current document to disk, with a name of your choice."));
		a->setShortcutText("");

		a=KStdAction::gotoLine(this, SLOT(gotoLine()), ac);
		a->setWhatsThis(i18n("This command opens a dialog and lets you choose a line that you want the cursor to move to."));
		a->setShortcutText("");

		a=KStdAction::selectAll(this, SLOT(selectAll()), ac);
		a->setWhatsThis(i18n("Select the entire text of the current document."));
		a->setShortcutText("");

		a=KStdAction::find(this, SLOT(find()), ac);
		a->setWhatsThis(i18n("Find text in the current document."));
		a->setShortcutText("");
	}

	void View::find() {
	}

	void View::save() {
		m_doc->save();
	}

	void View::saveAs() {
		QString s("browse confirm saveas");
		_vimWidget->sendCmdLineCmd( s );
	}

	void View::undo() {
		m_doc->undo();		
	}

	void View::redo() {
		m_doc->redo();		
	}

	void View::close() {
		m_doc->closeURL();
	}

	// -- ClipboardInterface ------------------------
	void View::cut() {
		QString s("\"+x");
		if (_vimWidget->useDCOP())
			_vimWidget->sendNormalCmd( s );
		else
			_vimWidget->sendRawCmd( s );
	}

	void View::copy() const {
		QString s("\"+y");
		if (_vimWidget->useDCOP())
			_vimWidget->sendNormalCmd( s );
		else
			_vimWidget->sendRawCmd( s );
	}

	void View::paste() {
		QString s("\"+gP");
		if (_vimWidget->useDCOP())
			_vimWidget->sendNormalCmd( s );
		else {
			s.prepend("<ESC>");
			_vimWidget->sendRawCmd( s );
		}
	}

	void View::gotoLine() {
		KEdGotoLine *goline = new KEdGotoLine (this);
		goline->exec();

		if( goline->result() != KEdGotoLine::Accepted)
	      return;

		_vimWidget->sendNormalCmd( QString("%1Gzz").arg(goline->getLineNumber()) );
	}

	void View::selectAll() {
		QString s("gggH\x0FG");
		_vimWidget->sendNormalCmd( s );
	}

	void View::emitCursorPositionChanged() {
		emit cursorPositionChanged();
	}
	
	void View::setDynWordWrap (bool wrap) {
		_vimWidget->setVimVariable("wrap", QString (wrap ? "true" : "false"));
	}
	
  bool View::dynWordWrap () const {
		QString s = _vimWidget->evalExpr("&wrap");
		bool wrap = (s[0] != '1');
		return wrap;
	}

/*	void View::keyPressEvent(QKeyEvent *e) {
		kdDebug(90000) << "keypress in View" << endl;
		e->ignore();
	}
	
	void View::mousePressEvent(QMouseEvent *e) {
		kdDebug(90000) << "mousepress in View" << endl;
		e->ignore();
	}*/

}

#include "vimview.moc"

