/***************************************************************************
                          hbcijob.h  -  description
                             -------------------
    begin                : Sun May 27 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 HBCIJOB_H
#define HBCIJOB_H

#ifdef __cplusplus
#include <string>
#include <list>
#endif /* __cplusplus */

#include <openhbci/pointer.h>
#include <openhbci/user.h>

#ifdef __cplusplus 
using namespace std;

namespace HBCI {
/**
 * @short Abstract base class for jobs.
 *
 * Let your jobs inherit this class to guarantee some important methods.
 * @author fabian kaiser
 */
class DLLIMPORT Job {
public:
    /**
     * This structure contains all information of an intitute-response to each part of the message<br>
     * get this information by calling getSegmentResponse
     */
    struct segResponse {
        int code;
        int replyTo;
        string text;
        string param;
        string additional;
        segResponse();
        segResponse(const string& response);
        ~segResponse();
        string toString() const;
    };

    /**
     * Create a new job for given user and given inst.
     */
    Job(Pointer<Customer> cust);

    virtual ~Job();

    /**
     * determins, whether a job needs to be signed<br>
     * if no job in the job-queue needs to be signed, the whole message
     * is transmitted without to be signed
     */
    virtual bool needsToBeSigned() const = 0;

    /**
     * determins, whether a job needs to be encrypted<br>
     * if no job in the job-queue needs to be encrypted, the whole message is
     * transmitted without to be encrypted
     */
    virtual bool needsToBeEncrypted() const = 0;

     /**
     * returns a string-representation of this job<br>
     * with this, the message is built
     */
    virtual string toString(int firstseg) = 0;

    /**
     * returns a list of all institute-resposes to each hbci-segment in
     * this job<br> the returned data-structure contains the response-code,
     * the responses-text and maybe some additional information
     */
    const list<segResponse>& getSegmentResponse() const;

    /**
     * determines, whether a given segment of the message is from this job
     */
    bool containsSegment(int number) const;

    /** The institute-response contains a short information about each
     * job. That information tells you whether the job succeeded or
     * whether there was an error. 
     *
     * This method is called by the MessageQueue. This method may be
     * called more than one time (if your job contains more than one
     * segment).  Each time it is called, you get the response for one
     * segment. FIXME: huh? how again does this method work?
     *
     * Get the content of the response by calling getSegmentResponse.
     *
     * @param response FIXME: add docs here */
    virtual void jobSuccess(const string& response);

    /**
     * the HBCI-object calls this method on each job.	<br>
     * all response-segment to one segment of your job are put into <response><br>
     * this method may be called more than one time (if your job contains
     * more than one segment).
     * each time it is called, you get the response for one segment
     */
    virtual void parseResponse(const string& response) = 0;

    /**
     * Get the number of segments used by this job.
     * @author Martin Preuss<martin@aquamaniac.de>
     */
    int segments() const { return _lastSegment-_startSegment+1;};

    /**
     * returns the number of the first segment
     * this is later needed for status reports
     * @author Martin Preuss<martin@aquamaniac.de>
     */
    int startSegment() const { return _startSegment;};

    /**
     * returns the number of the last segment
     * this is later needed for status reports
     * @author Martin Preuss<martin@aquamaniac.de>
     */
    int lastSegment() const { return _lastSegment;};

    /**
     * Returns a pointer to the owning customer of this job.
     */
    Pointer<Customer> owner() const {return _customer;};

    /** This method goes through all responses to this job, checks if
     * there was an error and returns <code>true</code> if this was
     * the case.  */
    bool hasErrors() const;

    /** Returns true if the given response code of a segment is due to
     * an error in the OpenHBCI library. If this is the case, an
     * application might consider submitting a bug report to
     * openhbci-general@lists.sf.net . */
    static bool errorcodeIsLibraryBug(int errorcode);

protected:
    Pointer<Customer> _customer;
    Pointer<User> _user;
    Pointer<Bank> _bank;
    list <segResponse> _responses;

    /** set the number of the first segment in toString() ! */
    int _startSegment;
    /** set the number of the last segment in toString() ! */
    int _lastSegment;

};

} /* namespace HBCI */
extern "C" {
#endif /* __cplusplus */
    extern int HBCI_Job_errorcodeIsLibraryBug(int errorcode);
#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
