/***************************************************************************
 $RCSfile: user.h,v $
                             -------------------
    cvs         : $Id: user.h,v 1.14 2003/04/15 22:10:23 cstim Exp $
    begin       : Sun Nov 18 2001
    copyright   : (C) 2001 by Martin Preuss
    email       : openhbci@aquamaniac.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                                                   *
 *                                                                         *
 ***************************************************************************/

/** @file user.h
 *
 * @short Definitions of HBCI::User and its @ref HBCI_User C wrapper.
 */

#ifndef HBCIUSER_H
#define HBCIUSER_H

#ifdef __cplusplus
namespace HBCI {
  class User;
};
#include <string>
#include <list>
using namespace std;
#include <openhbci/pointer.h>
/* for C wrapper functions */
/** @ingroup HBCI_Userg 
 * @short The C accessible type of HBCI::User .*/
typedef struct HBCI::User HBCI_User;
/** @ingroup HBCI_Userg */
typedef list<HBCI::Pointer<HBCI::User> > list_HBCI_User;
/** @ingroup HBCI_Userg */
typedef list<HBCI::Pointer<HBCI::User> >::const_iterator list_HBCI_User_iter;
#else /* __cplusplus */
typedef struct HBCI_User HBCI_User;
typedef struct list_HBCI_User list_HBCI_User;
typedef struct list_HBCI_User_iter list_HBCI_User_iter;
#endif /* __cplusplus */

#include <openhbci/medium.h>
#include <openhbci/customer.h>
#include <openhbci/bank.h>


#ifdef __cplusplus

namespace HBCI {

/**
 * @short Represents a user of a bank in HBCI 
 *
 * This class represents a user of HBCI at a bank. 
 *
 * A user is the owner of exactly one security medium. A user is
 * identified by its userId. 
 *
 * But to access a %HBCI account, a user takes on a given role which is
 * represented by @ref Customer (see there).
 *
 * @author Martin Preuss<openhbci@aquamaniac.de>
 */
class DLLIMPORT User {
private:
    Pointer<Bank> _bank;
    Pointer<Medium> _medium;
    string _userId;
    int _version;
    list<Pointer<Customer> > _customers;
    string _userName;
    bool _knowsSupportedUPDJobs;

public:
    /** 
     *  Constructor. 
     *
     * Creates a new user. Do not use this from an application
     * directly; instead, use HBCIAPI::userFactory.
     *
     * @param b The bank that this user belongs to.
     * @param m The medium that this user uses to authenticate himself.
     * @param uid The user ID that the bank assigned to this user.
     * @param version The UPD version.
     * @param userName The clear-text name of this user; this not 
     * given by the bank but can be arbitrarily chosen.  
	 * @param knowsSupportedUPDJobs True if the UPD contain all supported 
	 * jobs */
    User(Pointer<Bank> b,
	 Pointer<Medium> m,
	 const string &uid,
	 int version,
	 const string &userName,
	 bool knowsSupportedUPDJobs);

    /**  Copy Constructor. 
     * @param cu User that is copied. 
     */
    User(const User &cu);

    /**  Default Destructor. */
    ~User();

    /** @name Relation to other objects
     *
     * Methods to access the other objects this one belongs to. */
    /*@{*/
    /** 
     *  Returns a pointer to the bank that this user belongs to.
     */
    Pointer<Bank> bank() const { return _bank;};

    /** 
     *  Medium that this user owns.
     *
     * Returns a pointer to the secure medium that this user uses
     * to authenticate him/herself. 
     */
    Pointer<Medium> medium() const { return _medium;};
    
    /**
     *  Returns a reference to the list of customers. 
     *
     * Each customer is a "role" that this user may take during
     * talking to his bank.  */
    const list<Pointer<Customer> > &customers() const;

    /**
     *  Searches for the given customer.
     *
     * No wildcards or joker allowed.
     * @author Martin Preuss<openhbci@aquamaniac.de>
     * @param i customer id to look for
     */
    Pointer<Customer> findCustomer(const string &i) const;

    /**
     * Adds a customer to the list of customers that belong to this *
     * user. Throws an error if this customer already exists.
     *
     * @param cust The customer to add.
     */
    void addCustomer(Pointer<Customer> cust);
    /*@}*/

    /** @name User identification
     *
     * Information that identifies this user
     */
    /*@{*/
    /**
     *  The user ID that identifies this user to his bank. 
     *
     * Usually this string is assigned to the user by the bank.  */
    const string& userId() const { return _userId;};
    /*@}*/

    /** @name User information
     *
     * Additional information about this user
     */
    /*@{*/
    /**
     *  Returns the UPD version. 
     *
     * The UPD (%User Parameter Data, "UserParameterDaten") version
     * number is incremented by the bank each time it sends an updated
     * version of the UPD.  */
    int version() const { return _version;};
    /**
     *  Set the UPD version (%User Parameter Data). 
     *
     * This value should only be set through the related HBCI::Job.
     * @param v The version number.
     */
    void setVersion(int v) { _version=v;};

    /**
     *  Returns the clear-text name of this user.
     *
     * This is not set by the bank; instead, this can be set by the
     * application to any arbitrary string that is considered to be
     * helpful in identifiying this user.  */
    const string &userName() const { return _userName; };
    /**
     *  Set the clear-text name of this user.
     *
     * This is not set by the bank; instead, this can be set by the
     * application to any arbitrary string that is considered to be
     * helpful in identifiying this user.  
     * @param n The user name.
     */
    void setUserName(const string &n) { _userName = n; };

    /**
     * @short Tells you if you can rely on the result of
     * OutboxJobXXX::isSupported().
     *
     * If this method returns <code>false</code> then we don't have any
     * information if jobs like OutboxJobNewStandingOrder, OutboxJobTransfer
     * ... are supported for the specified Account.<br>
     * If <code>true</code> is returned, you can be sure that the results of
     * OutboxJobTransfer::isSupported() ... are valid.
     */
    bool knowsSupportedJobs() { return _knowsSupportedUPDJobs; };
    /**
     * @see knowsSupportedJobs()
     */
    void setKnowsSupportedJobs(bool knowsIt)
    { _knowsSupportedUPDJobs = knowsIt; };
    /*@}*/
};

} /* namespace HBCI */

#endif /* __cplusplus */

#ifdef __cplusplus
extern "C" {
#endif

    /** @defgroup HBCI_Userg HBCI_User functions */
    /*@{*/

    /** @name HBCI_User identification
     *
     * Information that identifies this user
     */
    /*@{*/
    /**
     *  The user ID that identifies this user to his bank. 
     *
     * Usually this string is assigned to the user by the bank.  
     * @param h The object to perform this action on.
     */
    extern const char* HBCI_User_userId(const HBCI_User *h);
    /**
     *  Returns the clear-text name of this user.
     *
     * This is not set by the bank; instead, this can be set by the
     * application to any arbitrary string that is considered to be
     * helpful in identifiying this user.  
     * @param h The object to perform this action on.
     */
    extern const char* HBCI_User_userName(const HBCI_User *h);
    /**
     *  Set the clear-text name of this user.
     *
     * This is not set by the bank; instead, this can be set by the
     * application to any arbitrary string that is considered to be
     * helpful in identifiying this user.  
     * @param h The object to perform this action on.
     * @param n The user name.
     */
    extern void HBCI_User_setUserName(HBCI_User *h, const char *n);
    /*@}*/

    /** @name HBCI_User Relation to other objects
     *
     * Methods to access the other objects this one belongs to. */
    /*@{*/
    /** 
     *  Medium that this user owns.
     *
     * Returns a pointer to the secure medium that this user uses
     * to authenticate him/herself. 
     * @param h The object to perform this action on.
     */
    extern const HBCI_Medium* HBCI_User_medium(const HBCI_User *h);
    /** 
     *  Returns a pointer to the bank that this user belongs to.
     * @param h The object to perform this action on.
     */
    extern const HBCI_Bank* HBCI_User_bank(const HBCI_User *h);
    /**
     *  Returns a reference to the list of customers. 
     *
     * Each customer is a "role" that this user may take during
     * talking to his bank.  
     * @param h The object to perform this action on.
     */
    extern const list_HBCI_Customer *HBCI_User_customers(const HBCI_User *h);
    /**
     *  Searches for the given customer.
     *
     * No wildcards or joker allowed.
     * @author Martin Preuss<openhbci@aquamaniac.de>
     * @param h The object to perform this action on.
     * @param custId customer id to look for
     */
    extern const HBCI_Customer *HBCI_User_findCustomer(const HBCI_User *h,
						       const char *custId);
    /**
     *  Adds a customer to the list of customers that belong to this
     * user.
     *
     * @param h The object to perform this action on.
     * @param cust The customer to add.
     * @param autoDelete If autoDelete==1 (TRUE), this HBCI_User will
     * also take ownership of the Customer and auto-delete the
     * customer if it is being deleted itself.
     * @return NULL on success, and the HBCI_Error on failure.
     */
    extern HBCI_Error *HBCI_User_addCustomer(HBCI_User *h,
					     HBCI_Customer *cust,
					     int autoDelete);
    /*@}*/

    /** @name C wrapper for list of Users 
     *
     * C wrapper for STL's list<User> type. To browse through a list,
     * get an iterator by list_HBCI_User_begin, increment it by
     * list_HBCI_User_iter_next, access its elements by
     * list_HBCI_User_iter_get, and see whether you're at the end of
     * the list by comparing with list_HBCI_User_iter_equal against
     * list_HBCI_User_end. */
    /*@{*/
    extern void list_HBCI_User_delete(list_HBCI_User *l);
    extern void list_HBCI_User_iter_delete(list_HBCI_User_iter *l);
    extern int list_HBCI_User_size(const list_HBCI_User *l);
    extern list_HBCI_User_iter* list_HBCI_User_begin(const list_HBCI_User *l);
    extern list_HBCI_User_iter* list_HBCI_User_end(const list_HBCI_User *l);
    extern const HBCI_User* 
    list_HBCI_User_iter_get(const list_HBCI_User_iter *l);
    extern void list_HBCI_User_iter_next(list_HBCI_User_iter *l);
    extern int list_HBCI_User_iter_equal(const list_HBCI_User_iter *l1, 
					 const list_HBCI_User_iter *l2);
    /** Callback function for list_HBCI_User_foreach. */
    typedef void *(*list_HBCI_User_cb) (const HBCI_User *user, 
					void *user_data);
    /** Traverses the list, calling the callback function 'func' on
     * each list element.  Traversal will stop when 'func' returns a
     * non-NULL value, and the routine will return with that
     * value. Otherwise the routine will return NULL. 
     * @param list The list to traverse.
     * @param func The function to be called with each list element.
     * @param user_data A pointer passed on to the function 'func'.
     * @return The non-NULL pointer returned by 'func' as soon as it
     * returns one. Otherwise (i.e. 'func' always returns NULL)
     * returns NULL.
     * @author Christian Stimming <stimming@tuhh.de> */
    extern void *list_HBCI_User_foreach (const list_HBCI_User *list, 
					 list_HBCI_User_cb func,
					 void *user_data);
    /*@}*/
    /*@}*/

#ifdef __cplusplus
} /* __cplusplus */

#endif



#endif




