/***************************************************************************
                          fileread.h  -  description
                             -------------------
    begin                : Wed May 23 2001
    copyright            : (C) 2001 by Javier Campos
    email                : javi@asyris.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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef FILEREAD_H
#define FILEREAD_H

#include <tdeio/job.h>

#include <tqdom.h>

// forward declarations
class KTempFile;

class TQFile;

/**File Read operations. This class read a keduca file an pass the records.
 *@author Javier Campos
 *@author Klas Kalass
 */

class FileRead : public TQObject {
    Q_OBJECT
  

public:
    FileRead( TQObject *parent=0, const char *name=0 );
    virtual ~FileRead();
    enum QuestionField { TQF_TEXT, TQF_PICTURE, TQF_POINTS, TQF_TYPE, TQF_TIME, TQF_TIP, TQF_EXPLAIN };
    enum AnswerField { AF_TEXT, AF_VALUE, AF_POINT };
    enum ResultField { RS_TEXT, RS_MIN, RS_MAX, RS_PICTURE };
    
    /** Open keduca file. This function can open a remote or local url. */
    bool openFile( const KURL &url );
    /** Set value to questions fields */
    void setQuestion( QuestionField field, const TQString& text);
    /** Set value to questions fields */
    void setQuestion( QuestionField field, int value );
    /** Set value to results fields */
    void setResult( ResultField field, const TQString& text);
    /** Set value to results fields */
    void setResult( ResultField field, int value );
    /** Insert an answer field */
    void setAnswer( const TQString& text, bool value, int points=0);
    /** Go to the Last Record */
    void recordLast();
    /** Go to the First record */
    void recordFirst();
    /** Go to the Last Record */
    void recordResultLast();
    /** Go to the First record */
    void recordResultFirst();
    /** Insert a blank question */
    void insertQuestion();
    /** Insert a blank result */
    void insertResult();
    /** Record Next */
    void recordNext();
    /** Record previous */
    void recordPrevious();
    /** Record Next */
    void recordResultNext();
    /** Record previous */
    void recordResultPrevious();
    /** Go to the Last Record */
    void recordAnswerLast();
    /** Go to the First record */
    void recordAnswerFirst();
    /** Record Next */
    void recordAnswerNext();
    /** Record previous */
    void recordAnswerPrevious();
    /** Move to record */
    void recordAnswerAt( unsigned int index);
    /** Record answer count */
    unsigned int recordAnswerCount();
    /** Get the value of the field question */
    TQString getQuestion( QuestionField field );
    /** Get the value of the field questions in integer */
    int getQuestionInt( QuestionField field );
    /** Get Answer field */
    TQString getAnswer( AnswerField field );
    /** Get answer field */
    int getAnswerPoints();
    /** Get Answer field */
    bool getAnswerValue();
    /** Get the value of the field result */
    TQString getResult( ResultField field );
    /** Get the value of the field result */
    int getResultInt( ResultField field );
    /** Returns if this record is a begin of file */
    bool recordBOF();
    /** Returns if this record is a end of file */
    bool recordEOF();
    /** Returns if this record is a begin of file */
    bool recordResultBOF();
    /** Returns if this record is a end of file */
    bool recordResultEOF();
    /** Returns if this record is a begin of file */
    bool recordAnswerBOF();
    /** Returns if this record is a end of file */
    bool recordAnswerEOF();
    /** Clear answers */
    void clearAnswers();
    /** Delete current record */
    void recordDelete();
    /** Swap two variables */
    void recordSwap( bool );
    /** Save file */
    bool saveFile( const KURL &url = KURL(), bool copyimages = false, bool saveCompressed = true );
    /** Save results */
    bool saveResults( const KURL &url, const TQString &results );
    /** Get real picture */
    TQString getPicture();
    /** Get real picture */
    TQPixmap getPicturePixmap();
    /** Set header data */
    void setHeader( const TQString field, const TQString value);
    /** Get Header */
    TQString getHeader(const TQString &head);
    /** is Multi Answer */
    bool isMultiAnswer();
    /** is Result */
    bool isResult();
    KURL const &getCurrentURL()const{return _currentURL;}
    /** @return true: The document has changed and should be saved*/
    bool changed() {return _changed;}
    /** Record at index */
    void recordAt( uint index );
    /** Refresh stadistical data - Points, number questions and total points */
    void refreshData();
    /* get total questions */
    uint getTotalQuestions();
    /* get total Points */
    uint getTotalPoints();
    /* get total Time */
    uint getTotalTime();
private:

    // Private attributes

    bool _changed;
    /** List of General Variables of the header */
    TQMap<TQString,TQString> _header;

    struct Answers
    {
        TQString text;
        bool value;
        int points;
    };

    struct Results
    {
        TQString text;
        TQString picture;
        int min;
        int max;
    };
    
    struct Questions
    {
        TQString text;
        int type;
        TQString picture;
        int time;
        int points;
        TQString tip;
        TQString explain;
        TQValueList<Answers> listAnswers;
        TQValueListIterator<Answers> recordAnswers;
    };

    /** List to Data struct */
    TQValueList<Questions> _listQuestions;
    TQValueListIterator<Questions> _recordQuestions;

    TQValueList<Results> _listResults;
    TQValueListIterator<Results> _recordResults;
    
    /** Returns if the database finds End Of File */
    bool _fileEOF;
    /** Returns if the database finds Bof Of File */
    bool _fileBOF;
    /** Returns if the database finds End Of File */
    bool _fileAnswerEOF;
    /** Returns if the database finds Bof Of File */
    bool _fileAnswerBOF;
    /** Returns if the database finds End Of File */
    bool _fileResultEOF;
    /** Returns if the database finds Bof Of File */
    bool _fileResultBOF;
    /** Current url */
    KURL _currentURL;
    /** the temporary file to which the document is saved, NULL if no temporary file is needed */
    KTempFile *_tmpfile;
    /** the temporary image file */
    TQString _tmpfileImage;
    /** Total Questions */
    uint _totalQuestions;
   /** Total Time */
    uint _totalTime;
    /** Total Points */
    uint _totalPoints;
    
    // Private methods

    /** Insert xml format data */
    void insertXML( TQDomDocument &doc, TQDomElement &parent, const TQString &tagName, const TQString &data);
    /** Insert xml data format */
    void insertXML( TQDomDocument &doc, TQDomElement &parent, const TQString &data);

protected:
    /** Open keduca file. This function does the actual work and expects a local filename . */
    bool loadFile( const TQString &filename );
    /** Save KEduca file to the file*/
    bool saveFile( const TQString &filename, bool copyimages, bool saveCompressed = true );
    /** Save Results file to the file */
    bool saveResults( const TQString &filename, const TQString &results );

protected slots:
    void slotUploadFinished( TDEIO::Job * job );

signals:
/* Stolen from tdeparts */

  /**
   * Emit this when you have completed loading data.
   * Hosting apps will want to know when the process of loading the data
   * is finished, so that they can access the data when everything is loaded.
   **/
  void completed();

  /**
   * Same as the above signal except besides indicating that the data has
   * been completely loaded it also informs the host, by setting the flag,
   * that a pending action has been generated as a result of completing the
   * requested task (loading the data).  An example of this is meta-refresh
   * tags on HTML pages which result in the page either being refreshed or
   * the viewer being redirected to another page.  By emitting this signal
   * after appropriately setting the flag, the part can tell the host of the
   * pending scheduled action inorder to give it a chance to accept or cancel
   * that action.
   *
   * @p pendingAction  if true, a pending action exists (ex: a scheduled refresh)
   */
  void completed( bool pendingAction );

  /**
   * Emit this if loading is canceled by the user or by an error.
   **/
  void canceled( const TQString &errMsg );

    /**
     * Emitted by the part, to set the caption of the window(s)
     * hosting this part
     */
    void setWindowCaption( const TQString & caption );

};

#endif
