/** 
 * Copyright (C) 1997-2002 the KGhostView authors. See file AUTHORS.
 * 	
 * 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; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef __KGV_MINIWIDGET_H
#define __KGV_MINIWIDGET_H

#include <qprinter.h>
#include <qsize.h>
#include <qstring.h>

#include "kgv.h"
#include "dscparse_adapter.h"
#undef min
#include "marklist.h"
#include "kpswidget.h"
#include "kgv_view.h"

class KPrinter;
class KTempFile;

class GotoDialog;
class InfoDialog;
class Pdf2dsc;

class KGVMiniWidget : public QObject
{
    Q_OBJECT

public:
    enum DocFormat { PS, PDF };
    
    KGVMiniWidget( KGVPart* part, const char* name = 0 );
    ~KGVMiniWidget();

    void readSettings();

    static QString pageSizeToString( QPrinter::PageSize );

    
/*- OPENING and READING ---------------------------------------------------*/

// private data used: _fileName, _psFile, _isFileOpen, _dsc, _format, _part 
//                    _tmpUnzipped, _tmpDSC
    
public:
    /**
     * Is a file currently open?
     */
    bool isFileOpen() const;

    /**
     * Open the @em local file @p filename asynchronously.
     */
    void openFile( const QString& filename, const QString& mimetype );

public slots:
    void fileChanged( const QString& );

signals:
    /**
     * Emitted if a fileChanged() call fails.
     */
    void fileChangeFailed();

    void completed();
    void canceled( const QString& );
    
protected:
    void scanDSC();
    void clearTemporaryFiles();
    
    void uncompressFile();
    void openPSFile(const QString &file=QString::null);

protected slots:
    void doOpenFile();
    void openPDFFileContinue( bool pdf2dscResult );

    
/*- DOCUMENT --------------------------------------------------------------*/

// private data used: _dsc, 
    
public:
    /**
     * @return the document structure for the current document, or 0 if no
     * file is loaded.
     */ 
    KDSC* dsc() const;
    
    /**
     * A list of page media (sizes).
     */
    QStringList mediaNames() const;
    const CDSCMEDIA* findMediaByName( const QString& mediaName ) const;

protected:
    QSize computePageSize( const QString& pageMedia ) const;

    
/*- PRINTING and SAVING ---------------------------------------------------*/

// private data used: 
//   Document specific: _dsc, _fileName, _format, _origurl
//   View specific:     _currentPage, _marklist 
//   This section only: _printer, _tmpFromPDF
    
public:
    /**
     * Returns a QString which contains a range representation of @p pageList.
     * Examples: [1,3]       -> "1,3"
     *           [1,2,3]     -> "1-3"
     *           [1,3,4,5,8] -> "1,3-5,8"
     */
    static QString pageListToRange( const KGV::PageList& );

public slots:
    void saveAs();
    void print();

protected:
    bool savePages( const QString& saveFileName,
                    const KGV::PageList& pageList );
    
    bool psCopyDoc( const QString& inputFile, const QString& outputFile,
                    const KGV::PageList& pageList );

    bool convertFromPDF( const QString& saveFileName, 
                         unsigned int firstPage, unsigned int lastPage );
   
    
/*- VIEWING ---------------------------------------------------------------*/

public: 
    void setPSWidget( KPSWidget* psWidget );

    void restoreOverrideOrientation();
    void setOverrideOrientation( CDSC_ORIENTATION_ENUM );
    
    void restoreOverridePageMedia();
    void setOverridePageMedia( const QString& mediaName );
    
    double magnification() const { return _magnification; }
    void setMagnification( double );
    
    CDSC_ORIENTATION_ENUM orientation() const;
    CDSC_ORIENTATION_ENUM orientation( int pageNo ) const;

    QString pageMedia() const;
    QString pageMedia( int pageNo ) const;

    KDSCBBOX boundingBox() const;
    KDSCBBOX boundingBox( int pageNo ) const;

    /**
     * Enable/disable fancy, document-supplied page labels.
     **/
    void enablePageLabels( bool e = true );
    bool arePageLabelsEnabled () { return _usePageLabels; }
        
    /**
     * Return true if the current page is the first page, false otherwise.
     */
    bool atFirstPage() const;
    /**
     * Return true if the current page is the last page, false otherwise.
     */
    bool atLastPage()  const;

    /**
     * Return true if we're zoomed in fully, false otherwise.
     */
    bool atMaxZoom() const;
    /**
     * Return true if we're zoomed out fully, false otherwise.
     */
    bool atMinZoom()  const;

    int currentPage() const { return _currentPage; }
    
public slots:
    bool prevPage();
    bool nextPage();
    void firstPage();
    void lastPage();
    void goToPage();
    void goToPage( int page );

    void zoomIn();
    void zoomOut();
    /*
    void fitWidth( unsigned int );
    void fitHeight( unsigned int );
    */
  
    void info();
    
    void configureGhostscript();

    /**
     * Redisplay the page if the file has changed on disk.
     **/
    void redisplay();
    
signals:
    /**
     * Page changed.
     */
    void newPageShown( int pageNumber );  // Should this one be under DOCUMENT?

    void setStatusBarText( const QString& );
    
protected:
    void showPage( int pageNumber );
    void buildTOC();

protected slots:
    void sendPage();
    void updateStatusBarText( int pageNumber );

   
/*- Conversion stuff ------------------------------------------------------*/
/*
    
// private data used: _interpreterPath

signals:
    void pdf2psFinished( bool );

protected:
    void pdf2psStart( const QString& pdfFile, const QString& psFile, 
                      unsigned int firstPage, unsigned int lastPage );

protected slots:
    void pdf2psExited( KProcess* );
*/    

/*- The REST --------------------------------------------------------------*/
    
protected:
    void reset();


private:
    QValueList<double> _fixedMagnifications;
    double _magnification;
    
    bool _usePageLabels;

    FILE* _psFile;
    int _currentPage;
    int _visiblePage;

    QString _fileName;
    QString _mimetype;

    MarkList* _marklist;

    InfoDialog *mInfoDialog;
    GotoDialog *mGotoDialog;

    KPSWidget* _psWidget;
    KGVPart*   _part;

    DocFormat _format;

    KTempFile* _tmpUnzipped;
    KTempFile* _tmpFromPDF;
    KTempFile* _tmpDSC;

    Pdf2dsc* _pdf2dsc;

    CDSC_ORIENTATION_ENUM _overrideOrientation;
    QString               _overridePageMedia;
    QString               _fallBackPageMedia;

    QString _interpreterPath;

    int toc_length;
    int toc_entry_length;

    bool _isFileOpen;

    KDSC* _dsc;
};

class Pdf2dsc : public QObject
{
    Q_OBJECT
	
public:
    Pdf2dsc( const QString& ghostscriptPath, QObject* parent = 0, const char* name = 0 );
    ~Pdf2dsc();
    
    void run( const QString& pdfName, const QString& dscName );
    void kill();
    
signals:
    void finished( bool result );

protected slots:
    void processExited();

private:
    KProcess* _process;
    QString   _ghostscriptPath;
};

inline KDSC* KGVMiniWidget::dsc() const
{
    return _dsc;
}

inline bool KGVMiniWidget::isFileOpen() const
{
    return _isFileOpen;
}

#endif
