/***************************************************************************
 $RCSfile: account.h,v $
 -------------------
 cvs         : $Id: account.h,v 1.17 2003/07/28 20:43:58 cstim Exp $
 begin       : Thu Nov 29 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                                                   *
 *                                                                         *
 ***************************************************************************/


#ifndef HBCI_ACCOUNT_H
#define HBCI_ACCOUNT_H

/** @file account.h
 *
 * @short Definitions of HBCI::Account and its @ref HBCI_Account C
 * wrapper.  */

#ifdef __cplusplus
#include <list>
#include <string>
using namespace std;
#include <openhbci/pointer.h>
#include <openhbci/dllimport.h>
namespace HBCI {
  class Account;
};
/* for C wrapper functions */
typedef list<HBCI::Pointer<HBCI::Account> > list_HBCI_Account;
typedef list<HBCI::Pointer<HBCI::Account> >::const_iterator list_HBCI_Account_iter;
typedef struct HBCI::Account HBCI_Account;
#else /* __cplusplus */
typedef struct HBCI_Account HBCI_Account;
typedef struct list_HBCI_Account list_HBCI_Account;
typedef struct list_HBCI_Account_iter list_HBCI_Account_iter;
#endif /* __cplusplus */

#include <openhbci/transaction.h>
#include <openhbci/value.h>
#include <openhbci/user.h>
#include <openhbci/customer.h>
#include <openhbci/bank.h>
#include <openhbci/balance.h>
#include <openhbci/standingorder.h>
#include <openhbci/limit.h>

#ifdef __cplusplus

namespace HBCI {

/**
 * @short The abstract base class for an account in OpenHBCI. 
 *
 * This is the abstract base class for an account in OpenHBCI.  You
 * can't create an object of this class directly; instead, use the
 * factory method provided in API::accountFactory. Internally this
 * class uses another class as implementation.
 * 
 * @author Martin Preuss<openhbci@aquamaniac.de> */
class DLLIMPORT Account {
public:
    /** 
     * Constructor
     */
    Account();
    /**
     * Destructor
     */
    virtual ~Account();

    /** @name Account identification
     *
     * Methods that return information to uniquely identify this account.
     */
    /*@{*/
    /** 
     *  Returns a pointer to the bank that this account belongs to.
     */
    virtual Pointer<Bank> bank() const =0;

    /** 
     *  Returns the account ID ("Kontonummer") of this account. 
     */
    virtual const string& accountId() const=0;

    /** 
     *  Returns the account ID suffix of this account. 
     *
     * Returns the account ID suffix of this account. This new in HBCI
     * 2.2; this field is only set by a few institutes */
    virtual const string& accountSuffix() const=0;

    /**
     * Returns the institute code (bank code, BLZ) of this account.
     *
     * Note: When creating a Transaction... do <i>not</i> use
     * Account::bank().ref().bankCode() but <i>instead</i> use
     * Account::instituteCode().  The reason is that the institute
     * code stored along with the account object may differ from the
     * code stored along with the bank object. (Don't blame openHBCI
     * for this fact.)
     */
    virtual const string &instituteCode() const=0;

    /**
     * Returns the country code of the bank of this account.
     *
     * Note: When creating a Transaction... do <i>not</i> use
     * Account::bank().ref().countryCode() but <i>instead</i> use
     * Account::countryCode().  The reason is that the country code
     * stored along with the account object may differ from the code
     * stored along with the bank object. (Don't blame openHBCI for
     * this fact.)
     */
    virtual int countryCode() const=0;
    /*@}*/

    /** @name Account information
     *
     * Methods that return additional information that OpenHBCI
     * learned about this account from the bank. */
    /*@{*/
    /**
     * @short Returns the name of the owner of this account. 
     * 
     * Unfortunately this has no standard relation to the <i>customers</i>
     * that are allowed to use this account. 
     */
    virtual const string& name1() const=0;

    /** @short Returns the second part of the name of the owner of
     * this account.  */
    virtual const string& name2() const=0;

    /** 
     * @short Returns the name of this account. 
     *
     * This is set by the bank.
     */
    virtual const string& accountName() const=0;

    /** 
     *  Returns the default currency of this account (DEM, EUR)
     */
    virtual const string& currency() const=0;
    /*@}*/

    /** @name Authorized Customers
     *
     * Methods that return information about which Customer is
     * authorized to sign transactions for this account. */
    /*@{*/
    /**  Returns the list of Customers that are authorized
     * to sign.
     *
     * Returns the list of Customers that are authorized to sign
     * (other expression: have signatory power) jobs/transactions on
     * this account.  */
    virtual const list<Pointer<Customer> > &authorizedCustomers() 
	const=0;

    /**
     * Adds an authorized customer to this account.
     */
    virtual void addAuthorizedCustomer(Pointer<Customer> c)=0;

    /** 
     *  Returns true if the given Customer is authorized to sign.
     *
     * Returns true if the given Customer is authorized to sign
     * jobs/transactions for this account.
     */
    virtual bool isAuthorized(const Pointer<Customer> c) const=0;
    /*@}*/

    /** @name Financial Application Data
     *
     * Methods to get and set data for financial applications, if
     * OpenHBCI is configured to manage that
     * data. (i.e. HBCI::isRetrievalOnly needs to be false) */
    /*@{*/
    /**   Returns the balance at the last time you checked it.
     *
     * Returns the balance of this account at the last time you
     * checked it, if you configure OpenHBCI such that it stores this
     * balance.  */
    virtual const AccountBalance &balance() const =0;

    /**   Returns the list of transactions up to the last time
     * you checked it.
     *
     * Returns the list of transactions of this account up to the last
     * time you checked it, if you configure OpenHBCI such that it
     * stores them.  */
    virtual const list<Transaction> &transactions() const=0;

    /**
     * Clears the list of transactions.
     */
    virtual void clearTransactions()=0;

    /**  Returns the list of standing orders up to the last time
     * you checked it.
     *
     * Returns a list of standing orders of this account, if you
     * configure OpenHBCI such that it stores them.
     *
     * @author Martin Preuss<martin@libchipcard.de> */
    virtual const list<StandingOrder> &standingOrders() const=0;

    /**
     * Clears the list of standing orders.
     */
    virtual void clearStandingOrders()=0;

    /**
     *  Adds a standing order to the list of standing orders.
     *
     * If there already is a standing order with the the same job id
     * then it will be overwritten. 
     * 
     * This operation only makes sense if you configure OpenHBCI such
     * that it stores the standing orders.
     *
     * @author Martin Preuss<martin@libchipcard.de> */
    virtual void addStandingOrder(const StandingOrder &o)=0;
    /*@}*/

    /** @name Account Management Enabled
     *
     * Methods to get and set the fact that this account is to be
     * managed through OpenHBCI at all. */
    /*@{*/
    /** 
     *  Returns true, if this account is to be managed by
     * OpenHBCI. 
     *
     * FIXME: Is this correct or is the boolean value the
     * other way round? Also, this is currently not really
     * implemented.
     *
     * You might want to set this to false if your bank does offer you
     * to manage this account through HBCI, but for whatever reason
     * you don't want to do this through this API. Deleting such an
     * account by removeAccount wouldn't help you, since at the next
     * UPD (user parameter data) update, which contain the list of
     * accounts, this account would pop up again in OpenHBCI.
     */
    virtual bool managed() const =0;
    /** 
     *  Set whether this account is to be managed by OpenHBCI.
     */
    virtual void setManaged(bool m)=0;
    /*@}*/

    /** @name General limit
     *
     * Methods returning information about a general limit of this
     * account, if it has one. */	
    /*@{*/

    /**
     * Returns the general limit for this account, if it has one.
     * If not, limit().isValid()=false.
     */
    virtual const Limit &limit()=0;

    /** 
     * @short <b>DEPRECATED</b> use limit() instead
     *
     * Returns the type of general limit this account has, if it has
     * one. (see HBCI-Spec V.3 Chapter User Parameter Data / account
     * information)
     *
     * Possible values: E - Einzelauftragslimit, T - Tageslimit, W -
     * Wochenlimit, M - Monatslimit, Z - Zeitlimit.
     */
    /*virtual char limitType() const=0;*/

    /**  
     * @short <b>DEPRECATED</b> use limit() instead 
     *
     * Returns the value of the general limit this account
     * has, if it has one. */
    /*virtual const Value &limitValue() const=0;*/

    /**  
     * @short <b>DEPRECATED</b> use limit() instead
     *
     * Returns the number of days for rotating time limits
     * (Zeitlimit), if this account has a time limit
     * (Zeitlimit). Otherwise this is zero.  */
    /*virtual int limitDays() const=0;*/
    /*@}*/

};
} /* namespace HBCI */
#endif /* __cplusplus */

#ifdef __cplusplus
extern "C" {
#endif
    /** @name HBCI_Account functions */
    /*@{*/
    /** 
     *  Returns a pointer to the bank that this account belongs to.
     */
    extern const HBCI_Bank* HBCI_Account_bank(const HBCI_Account *h);
    /** 
     *  Returns the account ID ("Kontonummer") of this account. 
     */
    extern const char* HBCI_Account_accountId(const HBCI_Account* h);
    /** 
     *  Returns the account ID suffix of this account. 
     *
     * Returns the account ID suffix of this account. This new in HBCI
     * 2.2; this field is only set by a few institutes */
    extern const char* HBCI_Account_accountSuffix(const HBCI_Account* h);
    /**
     * Returns the institute code (bank code, BLZ) of this account.
     */
    extern const char* HBCI_Account_instituteCode(const HBCI_Account* h);
    /**
     * Returns the country code of the bank of this account.
     */
    extern int HBCI_Account_countryCode(const HBCI_Account* h);
    /**
     * @short Returns the name of the owner of this account. 
     */
    extern const char* HBCI_Account_name1(const HBCI_Account* h);
    /** @short Returns the second part of the name of the owner of
     * this account.  */
    extern const char* HBCI_Account_name2(const HBCI_Account* h);
    /** 
     * @short Returns the name of this account. 
     *
     * This is set by the bank.
     */
    extern const char* HBCI_Account_accountName(const HBCI_Account* h);
    /** 
     *  Returns the default currency of this account (DEM, EUR)
     */
    extern const char* HBCI_Account_currency(const HBCI_Account* h);
    /**  Returns the list of Customers that are authorized
     * to sign.
     *
     * Returns the list of Customers that are authorized to sign
     * (other expression: have signatory power) jobs/transactions on
     * this account.  */
    extern const list_HBCI_Customer* 
    HBCI_Account_authorizedCustomers(const HBCI_Account *h);
    /** 
     *  Returns true if the given Customer is authorized to sign.
     *
     * Returns true if the given Customer is authorized to sign
     * jobs/transactions for this account.
     */
    extern int HBCI_Account_isAuthorized(const HBCI_Account *h, 
					 const HBCI_Customer *c);
    /**
     * Adds an authorized customer to this account. Returns NULL upon
     * success, or the appropriate HBCI_Error if there was one.
     *
     * @param h The object to perform this action on.
     *
     * @param c The customer that should added to the list of
     * authorized customers. That object will continue to be owned by
     * some other object (typically the HBCI_User), so it will @e not
     * be deleted by this object.
     */
    extern HBCI_Error *HBCI_Account_addAuthorizedCustomer(HBCI_Account *h,
							  const HBCI_Customer *c);

    /** 
     *  Returns true, if this account is to be managed by
     * OpenHBCI. 
     *
     * FIXME: Is this correct or is the boolean value the
     * other way round? Also, this is currently not really
     * implemented.
     */
    extern int HBCI_Account_managed(const HBCI_Account *h);
    /** 
     *  Set whether this account is to be managed by OpenHBCI.
     */
    extern void HBCI_Account_setManaged(HBCI_Account *h, int m);

    /**
     * Returns the general limit for this account, if it has one.
     * If not, limit().isValid()=false.
     */
    extern const HBCI_Limit *HBCI_Account_limit(HBCI_Account *h);
    /*@}*/

    /** @name list_HBCI_Account functions
     *
     * C wrapper for STL's list<Account> type. To browse through a
     * list, use list_HBCI_Account_foreach. Or if you want to do that
     * by hand: get an iterator by list_HBCI_Account_begin, increment
     * it by list_HBCI_Account_iter_next, access its elements by
     * list_HBCI_Account_iter_get, and see whether you're at the end
     * of the list by comparing with list_HBCI_Account_iter_equal
     * against list_HBCI_Account_end. */
    /*@{*/
    extern void list_HBCI_Account_delete(list_HBCI_Account *l);
    extern void list_HBCI_Account_iter_delete(list_HBCI_Account_iter *l);
    extern int list_HBCI_Account_size(const list_HBCI_Account *l);
    extern list_HBCI_Account_iter* 
    list_HBCI_Account_begin(const list_HBCI_Account *l);
    extern list_HBCI_Account_iter* 
    list_HBCI_Account_end(const list_HBCI_Account *l);
    extern const HBCI_Account* 
    list_HBCI_Account_iter_get(const list_HBCI_Account_iter *l);
    extern void 
    list_HBCI_Account_iter_next(list_HBCI_Account_iter *l);
    extern int 
    list_HBCI_Account_iter_equal(const list_HBCI_Account_iter *l1, 
				 const list_HBCI_Account_iter *l2);
    /** Callback function for list_HBCI_Account_foreach() . */
    typedef void *(*list_HBCI_Account_cb) (const HBCI_Account *account, 
					   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_Account_foreach (const list_HBCI_Account *list, 
					    list_HBCI_Account_cb func,
					    void *user_data);
    /*@}*/

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
