/***************************************************************************
 *   Copyright (C) 2005 by the G System Team                               *
 *   http://www.g-system.at                                                *
 *                                                                         *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the       *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to    *
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:                                             *
 *                                                                         *
 *   The above copyright notice and this permission notice shall be        *
 *   included in all copies or substantial portions of the Software.       *
 *                                                                         *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.                                       *
 ***************************************************************************/

#ifndef GWEFACTORYOPTIONH
#define GWEFACTORYOPTIONH

#include <qobject.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qdom.h>
#include <qmap.h>
#include <qvaluelist.h>

namespace GWE
{

/**
  \class GweFactoryOption GweFactoryOption.h
  \brief Option definition for server initialization.
  @author Raphael Langerhorst
  
  Options are ordered hierarchically like a tree structure.
  The user interface that lets the server administrator
  define the various options can have these represented
  in a treelike structure. Based on values of the current
  option different suboptions (leaves of the tree) are
  available. Thus only the options that are used are
  actually displayed.
  
  This class defines the base class for options. All
  specialisations are implemented in the implementation
  file of the GWoldEngineFactory class.
  
  To implement a specialised option class, only updateTree()
  needs to be reimplemented.
 */

class GweFactoryOption : public QObject
{
  Q_OBJECT
  
  protected:
  
    /**
   * Holds the name of the option. Thus it is possible to use
   * a class for more than just one option.
     */
    QString OptionName;
  
    /**
     * Description and explaination for the option.
     * Should be displayed in the UI if help is requested.
     */
    QString Description;
    
    /**
     * The actual value of the option. This determines
     * the initialization process of the GWE.
     */
    QString Value;
        
    /**
     * All suboptions in the options tree of this option.
     * The content depends on the value of this option.
     */
    QMap<QString,GweFactoryOption*> SubOptions;
    
  protected:
  
    /**
   * Deletes only the given sub option.
     */
    void deleteSubOption(const QString& option_name);
  
    /**
     * A useful method for clearing all suboptions.
     * This essentially deletes all suboptions and empties the value list.
     */
    void deleteAllSubOptions();
    
  public:
  
    /**
   * Constructor. All parameters except the name of the option are optional.
     */
    GweFactoryOption(const QString& option_name, const QString& value = 0, const QString& description = 0);
    
    /**
     * Destructor. Deletes all children.
     */
    virtual ~GweFactoryOption();
    
    /**
     * @return the name of the option.
     */
    QString getOptionName() const;
    
    /**
     * @return the option description which explains the option in-depth.
     */
    QString getDescription() const;
    
    /**
     * @return the value of the option which determines factory behaviour.
     */
    QString getValue() const;
    
    /**
     * @returns a reference to all suboptions.
     * 
     * @note The returned value list is a copy of the internal one. You
     *       should get a new one each time treeUpdated is emitted.
     */
    QValueList<GweFactoryOption*> getSubOptions() const;
    
    /**
     * @return the sub option with given option name.
     */
    GweFactoryOption* getSubOption(const QString& option_name);
    
    /**
     * @return the value of the given suboption (empty if value does not exist).
     */
    QString getValueOfSubOption(const QString& option_name);
    
    /**
     * If this option has predefined values, you can get the list of values
     * with getPredefinedValues.
     * @return true when this option can be set to some selected values only,
     *         false when the value is freeform (any string).
     * @note returns false if getPredefinedValues returns an empty list
     */
    bool hasPredefinedValues() const;
    
    /**
     * @return the list of predefined values that are valid for this option
     * @return an empty stringlist if the value can be any string, which means
     *         no predefined set of values is available.
     * @note returns an empty list by default, reimplement for different behaviour
     */
    virtual QStringList getPredefinedValues() const;
    
  public slots:
  
    /**
   * Updates recursively the available suboptions based on the
   * current value of this option.
   * This slot should be reimplemented in the specialised option class.
     */
    virtual void updateTree();
    
    /**
     * Sets the value of the option.
     * @see Value
     */
    virtual void setValue(const QString& value);
    
    /**
     * Sets the value of the option.
     * @see Value
     */
    virtual void setDescription(const QString& description);
    
    /**
     * Loads the configuration for this option including all suboptions
     * from given XML element (recursive).
     */
    virtual void loadFromXml(const QDomElement& options);
    
    /**
     * Saves the configuration for this option including all suboptions
     * to given XML element (recursive).
     */
    virtual void saveToXml(QDomElement storage);
    
    /**
     * Set the value of the given sub_option.
     * if the given suboption does not exist, nothing is done.
     */
    virtual void setValueOfSubOption(const QString& sub_option_name, const QString& value);
  
  signals:
  
    /**
     * Emitted every time the value of the option changes.
     * @see setValue
     */
    void valueChanged(const QString& new_value);
    
    /**
     * Emitted everytime the options tree is updated.
     * @see updateTree
     */
    void treeUpdated();
    
};

}

#endif
