/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          clayoutmanager.h  -  description
                             -------------------
    begin                : Thu May 22 2003
    copyright            : (C) 2000-2006 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;

namespace sptk {

   /// @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
