/***************************************************************************
* $Id$
**
* Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
**
* This file is part of an example program for Qt.  This example
* program may be used, distributed and modified without limitation.
**
****************************************************************************/
import org.kde.qt.*;
import java.util.*;


class HelpWindow extends QMainWindow
{
private   QTextBrowser browser;
private   QComboBox pathCombo;
private   int backwardId, forwardId;
private   String selectedURL;
private   ArrayList history = new ArrayList();
private   ArrayList bookmarks = new ArrayList();
private   HashMap mHistory = new HashMap();
private   HashMap mBookmarks = new HashMap();
private   QPopupMenu hist, bookm;




HelpWindow( String home_, String _path )
{
	this(home_, _path, null, null);
}

HelpWindow( String home_, String _path,
			QWidget parent, String name )
{
    super( parent, name, WDestructiveClose );
    readHistory();
    readBookmarks();

    browser = new QTextBrowser( this );

    browser.mimeSourceFactory().setFilePath( new String[] { _path } );
    browser.setFrameStyle( QFrame.Panel | QFrame.Sunken );
    connect( browser, SIGNAL(" textChanged()"),
	     this, SLOT(" textChanged()") );

    setCentralWidget( browser );

    if ( !home_.equals("") )
	browser.setSource( home_ );

    connect( browser, SIGNAL(" highlighted( String)"),
	     statusBar(), SLOT(" message( String)") );

    resize( 640,700 );

    QPopupMenu file = new QPopupMenu( this );
    file.insertItem( tr("&New Window"), this, SLOT(" newWindow()"), new QKeySequence(CTRL+Key_N) );
    file.insertItem( tr("&Open File"), this, SLOT(" openFile()"), new QKeySequence(CTRL+Key_O) );
    file.insertItem( tr("&Print"), this, SLOT(" print()"), new QKeySequence(CTRL+Key_P) );
    file.insertSeparator();
    file.insertItem( tr("&Close"), this, SLOT(" close()"), new QKeySequence(CTRL+Key_Q) );
    file.insertItem( tr("E&xit"), qApp(), SLOT(" closeAllWindows()"), new QKeySequence(CTRL+Key_X) );

    // The same three icons are used twice each.
    QIconSet icon_back = new QIconSet( new QPixmap("back.xpm") );
    QIconSet icon_forward = new QIconSet( new QPixmap("forward.xpm") );
    QIconSet icon_home = new QIconSet( new QPixmap("home.xpm") );

    QPopupMenu go = new QPopupMenu( this );
    backwardId = go.insertItem( icon_back,
				 tr("&Backward"), browser, SLOT(" backward()"),
				 new QKeySequence(CTRL+Key_Left) );
    forwardId = go.insertItem( icon_forward,
				tr("&Forward"), browser, SLOT(" forward()"),
				new QKeySequence(CTRL+Key_Right) );
    go.insertItem( icon_home, tr("&Home"), browser, SLOT(" home()") );

    QPopupMenu help = new QPopupMenu( this );
    help.insertItem( tr("&About ..."), this, SLOT(" about()") );
    help.insertItem( tr("About &Qt ..."), this, SLOT(" aboutQt()") );

    hist = new QPopupMenu( this );
    Iterator it = history.iterator();
	while (it.hasNext()) {
		String item = (String) it.next();
		mHistory.put(new Integer(hist.insertItem( item )), item);
	}
    connect( hist, SIGNAL(" activated( int )"),
	     this, SLOT(" histChosen( int )") );

    bookm = new QPopupMenu( this );
    bookm.insertItem( tr( "Add Bookmark" ), this, SLOT(" addBookmark()") );
    bookm.insertSeparator();

    Iterator it2 = bookmarks.iterator();
	while (it2.hasNext()) {
		String item = (String) it2.next();
	    mBookmarks.put(new Integer(bookm.insertItem( item )), item);
	}
    connect( bookm, SIGNAL(" activated( int )"),
	     this, SLOT(" bookmChosen( int )") );

    menuBar().insertItem( tr("&File"), file );
    menuBar().insertItem( tr("&Go"), go );
    menuBar().insertItem( tr( "History" ), hist );
    menuBar().insertItem( tr( "Bookmarks" ), bookm );
    menuBar().insertSeparator();
    menuBar().insertItem( tr("&Help"), help );

    menuBar().setItemEnabled( forwardId, false);
    menuBar().setItemEnabled( backwardId, false);
    connect( browser, SIGNAL(" backwardAvailable( boolean )"),
	     this, SLOT(" setBackwardAvailable( boolean )") );
    connect( browser, SIGNAL(" forwardAvailable( boolean )"),
	     this, SLOT(" setForwardAvailable( boolean )") );


    QToolBar toolbar = new QToolBar( this );
    addToolBar( toolbar, "Toolbar");
    QToolButton button;

    button = new QToolButton( icon_back, tr("Backward"), "", browser, SLOT("backward()"), toolbar );
    connect( browser, SIGNAL(" backwardAvailable(boolean)"), button, SLOT(" setEnabled(boolean)") );
    button.setEnabled( false );
    button = new QToolButton( icon_forward, tr("Forward"), "", browser, SLOT("forward()"), toolbar );
    connect( browser, SIGNAL(" forwardAvailable(boolean)"), button, SLOT(" setEnabled(boolean)") );
    button.setEnabled( false );
    button = new QToolButton( icon_home, tr("Home"), "", browser, SLOT("home()"), toolbar );

    toolbar.addSeparator();

    pathCombo = new QComboBox( true, toolbar );
    connect( pathCombo, SIGNAL(" activated( String )"),
	     this, SLOT(" pathSelected( String )") );
    toolbar.setStretchableWidget( pathCombo );
    setRightJustification( true );
    setDockEnabled( DockLeft, false );
    setDockEnabled( DockRight, false );

    pathCombo.insertItem( home_ );
    browser.setFocus();

}


void setBackwardAvailable( boolean b)
{
    menuBar().setItemEnabled( backwardId, b);
}

void setForwardAvailable( boolean b)
{
    menuBar().setItemEnabled( forwardId, b);
}


void textChanged()
{
    if ( browser.documentTitle() == null ) {
	setCaption( "Qt Example - Helpviewer - " + browser.context() );
	selectedURL = browser.context();
    }
    else {
	setCaption( "Qt Example - Helpviewer - " + browser.documentTitle() ) ;
	selectedURL = browser.documentTitle();
    }

    if ( !selectedURL.equals("") && pathCombo != null ) {
	boolean exists = false;
	int i;
	for ( i = 0; i < pathCombo.count(); ++i ) {
	    if ( pathCombo.text( i ) == selectedURL ) {
		exists = true;
		break;
	    }
	}
	if ( !exists ) {
	    pathCombo.insertItem( selectedURL, 0 );
	    pathCombo.setCurrentItem( 0 );
	    mHistory.put( new Integer(hist.insertItem( selectedURL )), selectedURL);
	} else
	    pathCombo.setCurrentItem( i );
	selectedURL = null;
    }
}

public void cleanUp()
{
    history.clear();
	Iterator it = mHistory.values().iterator();
	while (it.hasNext())
	    history.add(it.next());

    QFile f = new QFile( QDir.currentDirPath() + "/.history" );
    f.open( QIODevice.IO_WriteOnly );
    QTextStream t = new QTextStream( f );
	Iterator it1 = history.iterator();
	while (it1.hasNext()) {
		String item = (String) it1.next();
		t.writeRawBytes( item, item.length() );
		t.writeRawBytes( "\n", 1 );
	}
    f.close();

    bookmarks.clear();
	Iterator it3 = mBookmarks.values().iterator();
	while (it3.hasNext())
	    bookmarks.add(it3.next());

    QFile f2 = new QFile( QDir.currentDirPath() + "/.bookmarks" );
    f2.open( QIODevice.IO_WriteOnly );
    QTextStream t2 = new QTextStream( f2 );
	Iterator it2 = bookmarks.iterator();
	while (it2.hasNext()) {
		String item = (String) it2.next();
		t2.writeRawBytes( item, item.length() );
		t2.writeRawBytes( "\n", 1 );
	}
    f2.close();
}


void about()
{
    QMessageBox.about( this, "HelpViewer Example",
			"<p>This example implements a simple HTML help viewer "
			+ "using Qt's rich text capabilities</p>"
			+ "<p>It's just about 100 lines of Java code, so don't expect too much :-)</p>"
			);
}


void aboutQt()
{
    QMessageBox.aboutQt( this, "QBrowser" );
}

void openFile()
{
    String fn = QFileDialog.getOpenFileName( "", "", this );
    if ( !fn.equals("") )
	browser.setSource( fn );
}

void newWindow()
{
    ( new HelpWindow(browser.source(), "qbrowser") ).show();
}

void print()
{
    QPrinter printer = new QPrinter();//(QPrinter.HighResolution );
    printer.setFullPage(true);
    if ( printer.setup( this ) ) {
	QPainter p = new QPainter( printer );
	QPaintDeviceMetrics metrics = new QPaintDeviceMetrics(p.device());
	int dpix = metrics.logicalDpiX();
	int dpiy = metrics.logicalDpiY();
	int margin = 72; // pt
	QRect body = new QRect(margin*dpix/72, margin*dpiy/72,
		   metrics.width()-margin*dpix/72*2,
		   metrics.height()-margin*dpiy/72*2 );
	QFont font = new QFont("times", 10);
	ArrayList filePaths = browser.mimeSourceFactory().filePath();
	String file = "";
	Iterator it = filePaths.iterator();
	while (it.hasNext()) {
	    file = new QUrl( new QUrl((String) it.next()), new QUrl( browser.source() ).path() ).path();
	    if ( QFile.exists( file ) )
		break;
	    else
		file = "";
	}
	if ( file.equals("") )
	    return;
	QFile f = new QFile( file );
	if ( !f.open( QIODevice.IO_ReadOnly ) )
	    return;
	QTextStream ts = new QTextStream( f );
	QSimpleRichText richText = new QSimpleRichText( ts.read(), font, browser.context(), browser.styleSheet(),
				  browser.mimeSourceFactory(), body.height() );
	richText.setWidth( p, body.width() );
	QRect view = new QRect( body.topLeft(), body.bottomRight() );
	int page = 1;
	do {
	    richText.draw( p, body.left(), body.top(), view, colorGroup() );
	    view.moveBy( 0, body.height() );
	    p.translate( 0 , -body.height() );
	    p.setFont( font );
	    p.drawText( view.right() - p.fontMetrics().width( new Integer(page).toString() ),
			view.bottom() + p.fontMetrics().ascent() + 5, new Integer(page).toString() );
	    if ( view.top()  >= richText.height() )
		break;
	    printer.newPage();
	    page++;
	} while (true);
    }
}

void pathSelected( String _path )
{
    browser.setSource( _path );
	Iterator it = mHistory.values().iterator();
	boolean exists = false;
	while (it.hasNext()) {
	if ( ((String) it.next()).equals(_path) ) {
	    exists = true;
	    break;
	}
    }
    if ( !exists )
	mHistory.put( new Integer(hist.insertItem( _path )), _path);
}

void readHistory()
{
    if ( QFile.exists( QDir.currentDirPath() + "/.history" ) ) {
	QFile f = new QFile( QDir.currentDirPath() + "/.history" );
	f.open( QIODevice.IO_ReadOnly );
    QTextStream t = new QTextStream( f );
    while ( !t.atEnd() ) {
        String item = t.readLine();
		history.add((Object) item);
    }
	f.close();
	while ( history.size() > 20 )
	    history.remove( 0 );
    }
}

void readBookmarks()
{
    if ( QFile.exists( QDir.currentDirPath() + "/.bookmarks" ) ) {
	QFile f = new QFile( QDir.currentDirPath() + "/.bookmarks" );
	f.open( QIODevice.IO_ReadOnly );
    QTextStream t = new QTextStream( f );

    while ( !t.atEnd() ) {
        String item = t.readLine();
		bookmarks.add((Object) item);
    }
	f.close();
    }
}

void histChosen( int i )
{
    if ( mHistory.containsKey( new Integer(i) ) )
	browser.setSource( (String) mHistory.get( new Integer(i) ) );
}

void bookmChosen( int i )
{
    if ( mBookmarks.containsKey( new Integer(i) ) )
	browser.setSource( (String) mBookmarks.get( new Integer(i) ) );
}

void addBookmark()
{
    mBookmarks.put( new Integer(bookm.insertItem( caption() )), browser.context() );
}
}
