/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          clayoutmanager.h  -  description
                             -------------------
    begin                : Thu May 22 2003
    copyright            : (C) 2000-2005 by Alexey S.Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

/***************************************************************************
   This library is free software; you can redistribute it and/or modify it 
   under the terms of the GNU Library General Public License as published by
   the Free Software Foundation; either version 2 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 Library
   General Public License for more details.

   You should have received a copy of the GNU Library 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.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#ifndef __CLAYOUTMANAGER_H__
#define __CLAYOUTMANAGER_H__

class Fl_Image;

/// @addtogroup gui GUI Classes
/// @{

/// @brief Layout manager grow mode.
///
/// Allows or disables the layout to
/// grow in horizontal and/or vertical direction
enum CLayoutGrowMode {
   /// Don't allow layout to grow
   LGM_NONE,
   /// Allow horizontal grow only
   LGM_HORIZONTAL_GROW = 1,
   /// Allow vertical grow only
   LGM_VERTICAL_GROW = 2,
   /// Allow both horizontal and vertical grow
   LGM_AUTO_GROW = 3
};

/// @brief Layout Manager 
///
/// Maintains the position and size of the CLayoutClient-derived
/// objects in the attached group. It uses the CLayoutClient::layoutAlign() property 
/// of such objects and the output of CLayoutClient::preferredSize() to determine 
/// the widget's size and position.
/// @see CLayoutClient
class CLayoutManager {
protected:
   /// An extra space between widgets
   int               m_layoutSpacing;
   /// Layout grow mode
   /// @see CLayoutGrowMode
   CLayoutGrowMode   m_layoutGrowMode;
   /// Attached group to manage
   Fl_Group         *m_group;
   /// The background image
   Fl_Image         *m_backgroundImage;

   /// Does the auto layout computations and optional actual widget resizing
   /// @param x int, the layout x position, input
   /// @param y int, the layout y position, input
   /// @param w int&, the layout width, input/output
   /// @param h int&, the layout height, input/output
   /// @param resizeWidgets bool, resize widgets if true, or just compute the layout size
   void autoLayout(int x,int y,int& w,int& h,bool resizeWidgets) const;

   /// Paints background in tiles mode
   void paintBackground();
public:

   /// Default constructor
   CLayoutManager();

   /// Attaches the group to manage
   void attach(Fl_Group *group) { m_group = group;        }

   /// Returns current layout spacing between widgets
   int  layoutSpacing() const   { return m_layoutSpacing; }

   /// Defines layout spacing between widgets
   /// @param ls int, new layout spacing
   void layoutSpacing(int ls)   { m_layoutSpacing = ls;   }

   /// Defines layout grow mode
   /// @param gm CLayoutGrowMode, new layout grow mode
   /// @see CLayoutGrowMode
   void layoutGrowMode(CLayoutGrowMode gm=LGM_AUTO_GROW) { m_layoutGrowMode = gm; }

   /// Returns current layout grow mode
   /// @see CLayoutGrowMode
   CLayoutGrowMode layoutGrowMode() const { return m_layoutGrowMode; }

   /// Relayouts the attached group. It may be necessary if the inside widgets have changed
   /// content or shown/hidden.
   void relayout() { if (m_group) m_group->resize(m_group->x(),m_group->y(),m_group->w(),m_group->h()); }

   /// Defines the background image.
   /// @param img Fl_Image *, background image
   void backgroundImage(Fl_Image *img) { m_backgroundImage = img; }

   /// Returnes the current background image.
   Fl_Image *backgroundImage() const { return m_backgroundImage; }
};

/// @}

#endif
