/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *  
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *  
 * This file is part of NMM. 
 * 
 * NMM 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; only version 2 of the License.      
 * 
 * NMM 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 General Public 
 * License for more details.  
 * 
 * You should have received a copy of the GNU General Public License 
 * along with NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#ifndef _NMM_WIDGETS_HPP_
#define _NMM_WIDGETS_HPP_ _NMM_WIDGETS_HPP_

#include "nmm/nmm_prefix.hpp"

/*#include "nmm/utils/font/font.hpp"
#include "nmm/utils/bitmap/bitmapreader.hpp"*/
#include "nmm/plugins/video/osd/manager/interfaces/IWidgetImpl.hpp"
#include "nmm/plugins/video/osd/manager/interfaces/IWidgetCompositeImpl.hpp"

#include "Workspace.hpp"
#include "Callback.hpp"
#include "visibility.hpp"

namespace NMM {
  
  class DLLEXPORT OSDManagerNode;
  
  /** Widget base class. */
  class Widget : virtual public IWidgetImpl {
  protected:
    /**
     * the member function of the widget class is the key for our map
     * if we want to add a callback that should be executed if we call
     * Widget::selectLeft, we use Widget::selectLeft offset to build a
     * key for the map
     */
    //typedef void (Widget::* function_t) ( void );

    /* a list of Callback functions */
    typedef list<Callback*> callbacklist_t;

    /* the function(member) offset of the Widget class is used to build a key for the map */
    typedef map< string, callbacklist_t > callbacks_t;

    /* all callback functions a stored here */
    callbacks_t callbacks;

    /* x position of the widget in the workspace */
    unsigned int xpos;

    /* y position of the widget in the workspace */
    unsigned int ypos;

    /* width of the widget */
    unsigned int width;

    /* height of the widget */
    unsigned int height;
    
    /* widget id and manager */
    OSDManagerNode* manager;
    int id;
    
    /**
    * adjust width/height so that it dosn't extend the workspace width/height
    * \param xy x/y position that should added to the width/height
    * \param wh width/height
    * \param wh_dest workspace width/height
    * \returns width/height that is not larger than wh_dest and w if x/y is added
    */
    unsigned int adjustDimension( unsigned int xy, unsigned int wh, unsigned int wh_dest );

    /**
    * starts all callbacks that are attached to the map[id] entry
    * \param id identifier of the map
    */
    void startCallbacks( string id );


  public:
    Widget();
    virtual ~Widget() {};
    
    int getID() const { return id; }
    void setID(OSDManagerNode* manager, int id) {
      this->manager = manager;
      this->id = id;
    }
    
    /** IScrollable interface. */
    virtual nmm_int32 getScrollBarHeight() const;
    virtual nmm_int32 getScrollBarWidth() const;
    virtual nmm_int32 getScrollBarYPosition() const;
    virtual nmm_int32 getScrollBarXPosition() const;
    
    /** IWidget interface. */
    virtual nmm_int32 getWidgetID() const;
    virtual void selectRight();
    virtual void selectLeft();
    virtual void selectUp();
    virtual void selectDown();
    virtual void selectPush();
    virtual void setPosition(const nmm_uint32& x, const nmm_uint32& y);
    virtual void setDimension(const nmm_uint32& w, const nmm_uint32& h);
    virtual void getPosition(nmm_uint32& x, nmm_uint32& y) const;
    virtual void getDimension(nmm_uint32& w, nmm_uint32& h) const;
    
    /**
     * Add callback function.
     * @param id member function offset to add callback function to
     * @param cb pointer to function that should be added
     */
    void connectTo( string id, class Callback* cb );
    
    /**
     * Removes callback function.
     * @param id member function offset which callbacks should be removed
     */
    void disconnect( string id );
    
    /**
     * draw the widget to a rgba workspace
     * @param ws pointer to a workspace (rgba format)
     */
    virtual void draw( workspace_t* ws ) = 0;
    
  }; // Widget
  
  
  class WidgetComposite : public Widget,
                          public IWidgetCompositeImpl {
  protected:
    list<Widget*> widgetlist;
    
  public:
    WidgetComposite();
    ~WidgetComposite();
    
    /** IWidgetComposite interface. */
    virtual void add( const IWidget& wg);
    virtual void remove( const IWidget& wg );
    virtual void removeAll();
    
    virtual void draw( workspace_t* ws );
  };
  


} // NMM

#include "nmm/nmm_suffix.hpp"

#endif //_NMM_WIDGETS_HPP_
