/***************************************************************************
  $RCSfile: mediumplugin.h,v $
  -------------------
  cvs         : $Id: mediumplugin.h,v 1.11 2003/05/19 16:09:06 cstim Exp $
  begin       : Mon Apr 14 2003
  copyright   : (C) 2003 by Martin Preuss
  email       : martin@libchipcard.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 mediumplugin.h Declaration of the abstract base class for a
 * medium plugin.
 */

#ifndef MEDIUMPLUGIN_H
#define MEDIUMPLUGIN_H

#include <openhbci/plugin.h>
#include <openhbci/medium.h>

#ifdef __cplusplus
#include <openhbci/simpleconfig.h>
#include <string>
using namespace std;

namespace HBCI {

/**
 * @brief This is the abstract base class for a medium plugin.
 *
 * Note: If you are writing a new medium plugin, then the *first*
 * class your new medium class has to inherit is "HBCI::Medium" (not
 * the other way round)!  It took me several hours to figure out why
 * MediumDDV did not work.
 *
 * @author Martin Preuss<martin@libchipcard.de>
 * @see @ref pluginpage
 */
class MediumPlugin: public Plugin {
public:
  /** Default Constructor */
  MediumPlugin();
  /** Default Destructor */
  virtual ~MediumPlugin();

  /**
   * Returns the type of this plugin.
   */
  virtual PluginType pluginType() const { return PluginTypeMedium;};

  /**
   * Returns the name of the MediumType (such as "RSACard", "DDVCard").
   */
  virtual string mediumTypeName() const=0;

  /**
   * Returns the generalized medium type (either file of card).
   */
  virtual MediumType mediumType() const=0;

  /**
   * This method should only be used if there is no configuration file.
   * It creates a medium with default settings. This method MUST only
   * be used for media that already exist (like cards, already existing
   * files etc).
   */
  virtual Pointer<Medium> mediumFactory(const string &name)=0;

  /**
   * This method checks whether the given name resolves to a medium
   * of this type. A file medium might check whether the file has the
   * correct format, a card plugin might check whether the inserted card
   * is the correct type.
   * If the returned error code indicates success, then the medium is
   * a valid medium with regard to this plugin.
   * If the returned error code is HBCI_ERROR_CODE_BAD_MEDIUM then it is
   * suggested that this medium is not supported by the plugin.
   * All other error codes indicate an error, but only
   * HBCI_ERROR_CODE_BAD_MEDIUM  will be treated as a  definitive NACK.
   * This means any other error code should not lead to the conclusion that
   * the medium is not supported.
   * In such a case it would be best for the application to retry (if the
   * error advise() suggests so).
   * If this medium plugin supports card media, then the following rules
   * additionally apply:
   * <ul>
   * <li>
   *  If the parameter "name" is empty, then on success this method may
   *  set the name of this medium (in most cases this is the serial
   *  number of the card
   * </li>
   * <li>
   *  If the parameter "name" is NOT empty, then the plugin MUST check
   *  whether the name is correct (i.e. if the serial number matches the
   *  given card). If the name does not match this method MUST return
   *  HBCI_ERROR_CODE_WRONG_MEDIUM.
   * </li>
   * </ul>
   * However, if the plugin does not support this method at all it MUST
   * return HBCI_ERROR_CODE_UNSUPPORTED.
   *
   * @return Error code
   *
   * @param name Name which identifies the medium (similar to
   * HBCI::Medium::mediumName(). For a file plugin this parameter MUST
   * be the filename of the medium and MUST NOT be empty. For a card
   * medium this parameter may be empty, and on success the found card
   * medium's name will be returned in this string.
   */
  virtual Error mediumCheck(string &name) const;

  /**
   * Create a new medium using the data given.
   * A keyfile medium will create a new file, a card medium will
   * most likely do nothing.
   */
  virtual Pointer<Medium> createNewMedium(bool readonly,
					  int country,
					  const string &bankId,
					  const string &userid,
					  const string &name)=0;

  /**
   * This method is used to create a medium object using the data given in
   * a configuration file.
   * There are some mandatory variables in this group:
   * <ul>
   *  <li>
   *   mediumtype: This is used to lookup the medium plugin that is
   *   responsible for this medium
   *  </li>
   *  <li>
   *   mediumname: This is used to identify a medium. Each medium MUST have
   *   a unique name. RDHFiles use the path and name of the keyfile here,
   *   while chipcard media use the card's serial number.
   *  </li>
   * </ul>
   * The plugin may additionally use whichever variables it finds necessary.
   */
  virtual Pointer<Medium> mediumFromConfig(SimpleConfig &cfg,
					   cfgPtr group)=0;

  /**
   * This method is used to store information from a medium to a configuration
   * file (in order to be restorable by @ref mediumFromConfig).
   * See @ref mediumFromConfig for details about the config group.
   */
  virtual Error mediumToConfig(Pointer<Medium> m,
			       SimpleConfig &cfg,
			       cfgPtr group)=0;

};


};
typedef HBCI::MediumPlugin HBCI_MediumPlugin;
extern "C" {
#else /* __cplusplus */
  typedef struct HBCI_MediumPlugin HBCI_MediumPlugin;
#endif /* __cplusplus */
  /** @name HBCI_MediumPlugin
   *
   * Wrappers for HBCI::MediumPlugin */
  /*@{*/
  /** Upcast */
  extern const HBCI_Plugin *
  HBCI_MediumPlugin_Plugin(const HBCI_MediumPlugin *m);

  /**
   * Returns the name of the MediumType (such as "RSACard", "DDVCard").
   *
   * Note: The returned string will be owned by the caller and has to
   * be free()'d be the caller when no longer needed! */
  extern char *
  HBCI_MediumPlugin_mediumTypeName(const HBCI_MediumPlugin *m);
  
  /**
   * Returns the generalized medium type (either file of card).
   */
  extern MediumType HBCI_MediumPlugin_mediumType(const HBCI_MediumPlugin *m);
  
  /**
   * This method checks whether the given name resolves to a medium
   * of this type.  
   *
   * Note: This C function implements the MediumPlugin::mediumCheck
   * for the case when a medium name is specified by the application.
   *
   * A file medium might check whether the file has the
   * correct format, a card plugin might check whether the inserted card
   * is the correct type.
   * If the returned error code indicates success, then the medium is
   * a valid medium with regard to this plugin.
   * If the returned error code is HBCI_ERROR_CODE_BAD_MEDIUM then it is
   * suggested that this medium is not supported by the plugin.
   * All other error codes indicate an error, but only
   * HBCI_ERROR_CODE_BAD_MEDIUM  will be treated as a  definitive NACK.
   * This means any other error code should not lead to the conclusion that
   * the medium is not supported.
   * In such a case it would be best for the application to retry (if the
   * error advise() suggests so).
   * If this medium plugin supports card media, then the following rules
   * additionally apply:
   * <ul>
   * <li>
   *  If the parameter "name" is empty, then on success this method may
   *  set the name of this medium (in most cases this is the serial
   *  number of the card
   * </li>
   * <li>
   *  If the parameter "name" is NOT empty, then the plugin MUST check
   *  whether the name is correct (i.e. if the serial number matches the
   *  given card). If the name does not match this method MUST return
   *  HBCI_ERROR_CODE_WRONG_MEDIUM.
   * </li>
   * </ul>
   * However, if the plugin does not support this method at all it MUST
   * return HBCI_ERROR_CODE_UNSUPPORTED.
   *
   * @return Error code
   *
   * @param m The object to perform this action on.
   *
   * @param check_name name which identifies the medium (similar to
   * HBCI::Medium::mediumName(). This MUST NOT be empty in this
   * function.
   */
  extern HBCI_Error *HBCI_MediumPlugin_mediumCheck(const HBCI_MediumPlugin *m, 
						   const char *check_name);
  /**
   * This method checks whether the given name resolves to a medium
   * of this type.  
   *
   * Note: This C function implements the MediumPlugin::mediumCheck
   * for the case when no medium name has been specified by the
   * application and the found medium name is return by OpenHBCI.
   *
   * For more description see HBCI_MediumPlugin_mediumCheck().
   *
   * @return Error code
   *
   * @param m The object to perform this action on.
   *
   * @param find_name Pointer to char where the name which identifies
   * the medium is returned (similar to
   * HBCI::Medium::mediumName(). The found card medium's name will be
   * returned in this pointer, or NULL if an exception occurred, was
   * caught, and returned as error. The string will be owned by the
   * caller and has to be free()'d by the caller when no longer
   * needed.
   */
  extern HBCI_Error *
  HBCI_MediumPlugin_mediumCheck_findname(const HBCI_MediumPlugin *m, 
					 char **find_name);
  /*@}*/
#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif

