/***************************************************************************
                          hbcimessagequeue.h  -  description
                             -------------------
    begin                : Thu Jul 26 2001
    copyright            : (C) 2001 by fabian kaiser
    email                : fabian.kaiser@gmx.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   This library 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     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
 *   MA  02111-1307  USA                                                   *
 *                                                                         *
 ***************************************************************************/

/*
 */

#ifndef HBCIMESSAGEQUEUE_H
#define HBCIMESSAGEQUEUE_H

#include <string>
#include <list>

#include <openhbci/dllimport.h>
#include <openhbci/pointer.h>
#include <openhbci/date.h>
#include <openhbci/hbci.h>
#include <openhbci/job.h>
#include <openhbci/medium.h>
#include <openhbci/customer.h>
#include <openhbci/bank.h>
#include <openhbci/statusreport.h>

using namespace std;

namespace HBCI {

/** 
 * @short Represents the servers responses to any segments that 
 * don't belong to a sent job.
 *
 * This class represents the servers responses to any segments that 
 * don't belong to a sent job.<br>
 * This way you can get detailed information about the 
 * HIRMG (response wich tells you about the success of the whole message)
 * and about HIRMS that don't belong to a job as mentioned above.<br>
 * use hbcimessagequeue::generalMessage() to retrieve a list of these responses
 * @author fabian.kaiser@gmx.de
 */
class DLLIMPORT GeneralSegResponse {
public:
  /** 
   * Create a GeneralSegResponse with the specified params 
   * @author fabian.kaiser@gmx.de
   * @param refSEG @see getRefSEG
   * @param refDE @see getRefDE
   * @param returnCode @see getRetCode
   * @param message @see getMessage */
    GeneralSegResponse(int refSEG,
                       int refDE,
                       int returnCode,
                       string message);

  /**
   * Parse the given response-segment and create a GeneralSegResponse
   * from it
   * @see GeneralSegResponse(int, int, int, string)
   * @author fabian.kaiser@gmx.de
   */
  GeneralSegResponse(string &respSegment);

  int refSEG;
  int refDE;
  int returnCode;
  string message;
};


/**
 * @short This class is queueing all Job's that you want to send
 * at the same time.
 *
 * This class is responsible for queueing all the Job -s you want
 * to send to the inst. at one time.  
 *
 * After having read the servers response, the response is divided up
 * into parts, where each part is the response to one single
 * job. These parts are used to call the method <b>parse</b> on each
 * Job.  This way, each job is responsible for it's response.
 *
 * @author fabian kaiser, Martin Preuss */
class DLLIMPORT MessageQueue {
private:
    Pointer<Customer> _customer;
    list<Pointer<Job> > _jobqueue;
    list<Pointer<Customer> > _signers;
    list<instituteMessage> _bankmessages;
    int _msgnumber;
    string _dialogid;
    string _response;
    int _result;
    bool _syncmode;

    /**
     * current medium, is used between sending a message and decoding the
     * answer.
     */
    Pointer<Medium> _medium;

    void parseGeneralResponse(string respMsg);

    Error _mountCustomersMedium(Pointer<Customer> cust);

public:
    list<GeneralSegResponse> generalMsg;

    /**
     * creates a new messagequeue
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    MessageQueue(Pointer<Customer> cust);

    ~MessageQueue();

    /**
     * This is needed to allow synchronization of the systemid even if
     * we already have a systemid.
     */
    void setSyncMode(bool sync) { _syncmode=sync;};

    /**
     *
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    void reset();

    /**
     * enqueue a job for later transmission via sendData<br>
     * @author Martin Preuss<openhbci@aquamaniac.de>
     * @return true if job could be enqueued
     * @return false on error
     */
    bool addJob(Pointer<Job> newJob);

    /**
     * most jobs need to be signed (some with more than one signature)
     * the last user that is added will be the main signer
     * please note that you MUST not add the customer that owns
     * this message box, because he gets added automatically.
     * add a second (or maybe a third) if more than one signature is needed
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    bool addSigner(Pointer<Customer> newSigner);

    /**
     * create a hbci-conform string-representation of this message box
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    string toString(int message_number);

    /**
     * Returns the dialog id.
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    string dialogId();

    /**
     * Returns the current message number
     */
    int messageNumber() const { return _msgnumber;};

    MessageReference messageReference() const;

    /**
     * Parses the response.
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    bool setResponse(string response);

    /**
     * Returns the return code for the whole message.
     *
     * All values v with v < 1000 mean success. All values v with 3000
     * <= v < 4000 are warnings. All values with 9000 <= v < 10000 are
     * supposed to be errors. However, the authoritative decision
     * whether there has been an error or not is done by the method
     * hasErrors(), so please <i>check that method first</i>.
     *
     * If you got an error code here, you can use
     * Job::errorcodeIsLibraryBug() to determine whether the error is
     * due to a bug in the OpenHBCI library. If this is not the case,
     * then please check the %HBCI specification, section II.8.5.4.3,
     * on what this error code means.
     *
     * NOTE: The return value of this method has to be interpreted
     * with care. The result code returned here could indicate an
     * error even if there is none, or sometimes there are errors
     * which can be ignored (e.g. No Sign Key from the institute).
     *
     * @see hasErrors()
     * @see Job::errorcodeIsLibraryBug()
     * @author Martin Preuss<openhbci@aquamaniac.de> */
    int getResult();

    /**
     * Check whether the message queue is empty
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    bool empty();

    /**
     * Return the number of jobs already in this queue
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    int size();

    /**
     * Check if any of the jobs in the box has errors.
     *
     * This is a conveniance method that checks each job enqueued to
     * this messagequeue for errors. If any of the jobs failed this method
     * returns TRUE.
     *
     * @author Martin Preuss<openhbci@aquamaniac.de>
     * @return true if there is at least ONE job with errors
     */
    bool hasErrors();

    /**
     * Returns a pointer to the customer which owns this queue.
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    Pointer<Customer> owner() { return _customer;};

    /**
     * Returns a list of instituteMessages collected in the last session.
     * This list is cleared upon @ref reset().
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    list<instituteMessage> &bankMessages() { return _bankmessages;};

};

} /* namespace HBCI */

#endif
