/*
 * --- GSMP-COPYRIGHT-NOTE-BEGIN ---
 * 
 * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
 * Please add additional copyright information _after_ the line containing
 * the GSMP-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
 * the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
 * 
 * GSMP: dam/include/Definition.hh
 * General Sound Manipulation Program is Copyright (C) 2000 - 2004
 *   Valentin Ziegler and René Rebe
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2. A copy of the GNU General
 * Public License can be found in the file LICENSE.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANT-
 * ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * 
 * --- GSMP-COPYRIGHT-NOTE-END ---
 */
/* InsertCopyright *
 * InsertInfo      */

#ifndef DAM__DEFINITION_HH__
#define DAM__DEFINITION_HH__

#include "Signals.hh"
#include "State.hh"
#include "Binding.hh"
#include "DefinitionSpecs.hh"

namespace DAM
{
  typedef std::string Id__;
  typedef const Id__ id;

  class DefinitionTraits
  {
  public:
    static const bool permanent = false;
    static const bool public_data = false;
    static const bool nomatch_reasons = false;
    static const bool auto_expire = true;
  };

  class BasicDefinitionMap;

  class DefinitionBinding : public BasicBinding
  {
  public:
    typedef BasicDefinitionMap Map;

    DefinitionBinding (Map* map, Id id);

    Id GetId () const          {return id;}
    Map* GetMap ()             {return map;}
    const Map* GetMap () const {return map;}
  private:
    Map* map;
    Id__ id;
  };


  class BasicDefinition : public Automaton <BasicDefinition_State, LoggingDefinitions>
  {
  public:


    //Dependency List
  private:
    unsigned int counter;
  };


  template <typename D_DATA, typename D_NOMATCH, typename D_TRAITS>
  class Definition
  {
  public:
    Definition (D_DATA definition, BindingList& dependence);
    Definition (D_DATA definition);
    ~Definition ();

    virtual bool Agrees (const D_DATA& with) const;

    const D_DATA& Data () const;
    const D_NOMATCH& Reason ();

  protected:
    D_DATA data;

  };


  /**********************************************************************/

  class DefinitionMapBase
  {
  public:
    void UnDeclare (ID id);

    Event1<Id> Defined;
    Event1<Id> Virtualized;
    Event1<Id> Expired;

    const DefinitionBase& GetDefinitionBase (Id) const;
    bool Exists (Id);
  };

  class DefinitionError
  {
  public:
    bool conflict; // conflicts existing definition
  };

  template <typename D_DATA, D_ERROR>
  class Binder
  {
  public:
    BindingList bindings;
    D_ERROR definition_error; 
    virtual bool CreateBindings (D_DATA& definition) {};
  };

  template <typename D_DATA, typename D_NOMATCH, typename D_ERROR, typename D_TRAITS, typename BINDER>
  class DefinitionMap : public DefinitionMapBase
  {
  public:
    bool Declare (ID id, const D_DATA& declaration);
    bool Check (ID id, const D_DATA& declaration) const;

    const D_DATA& GetData (ID id) const;
    const D_ERROR& GetDefinitionError () const;
    const D_NOMATCH& GetConflict () const;
    const Definition<D_DATA, D_NOMATCH, D_TRAITS>& GetDefinition (Id) const;
  };


} // end namespace DAM


/* include template implementation */
#define DAM__DEFINITION_TMPL__
#include "template/Definition.tcc"
#undef DAM__DEFINITION_TMPL__

#endif // DAM__DEFINITION_HH__
