/*
 * widgets/ScrollbarWidget.h:
 *
 * Copyright (C) 2000 John Watson, jwatson@tempusmud.com
 * 
 * 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; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

#ifndef __ScrollbarWidget_h__
#define __ScrollbarWidget_h__

#include "Widget.h"
#include "ButtonWidget.h"
#include "WidgetEvents.h"

/**
 * the type of scrollbar end button
 */
enum ScrollbarEndType { SB_NEAR = 0, SB_FAR = 1 };



/**
 * the scrollbar widget, contains and elevator and 2 end buttons
 *
 */
class ScrollbarWidget : public Widget, public WidgetEventListener {

        friend class ScrollbarElevatorWidget;
        friend class ScrollbarButtonWidget;

        enum ScrollType _type;
        
        GLuint _railListIndex;
        
        /**
         * ratio of scrollbar rail pixels to viewport view pixels
         */
        double _pixelRatio;
        int _railLen;
        int _railTravelLen;
        int _railMargin;

        class ScrollbarElevatorWidget *_elevatorWidget;
        class ScrollbarButtonWidget * _buttons[2];
        class Viewport * _scrollViewport;

        static const int MIN_SCROLLBAR_LEN = 8;

        int attemptSlide( int amount );

        /**
         * internal utility method to find out how long the elevator should be, based on the view properties
         */
        int getElevatorSize();

        /**
         * internal utility that resets _railTravelLen, _pixelRatio, and repositions the elevator
         */
        void resetInternals();

public:

        ScrollbarWidget( int w, int h, 
                         enum ScrollType type,
                         class Viewport *viewport );
        
        ~ScrollbarWidget();

        void paint();
        
        bool mousePressed( SDL_MouseButtonEvent * evt );
  
        virtual void handleEvent( const class WidgetEvent * evt );

        bool keyPressed( SDL_KeyboardEvent * evt, int x, int y );

};


/**
 * the elevator button, is resized on the fly
 *
 */
class ScrollbarElevatorWidget : public ButtonWidget {
        GLuint _displayListIndex;
        class ScrollbarWidget *_scrollbar;
        /** coordinate along the slider's major axis, relative to the origin of the elevator */
        int _grabbedAtRelative;
public:
        ScrollbarElevatorWidget( int w, int h, class ScrollbarWidget *scrollbar );
        void paint();
        bool mousePressed( SDL_MouseButtonEvent * evt );
        bool mouseReleased( SDL_MouseButtonEvent * evt );
        virtual bool mouseMoved( SDL_MouseMotionEvent * evt );
        
        int getLength() const { return _size[ _scrollbar->_type ]; };
};


/**
 * the scrollbar end button
 *
 */
class ScrollbarButtonWidget : public ButtonWidget {
        class ScrollbarWidget *_scrollbar;
        ScrollbarEndType _endType;
public:
        ScrollbarButtonWidget( int w, int h, enum ScrollbarEndType endType, class ScrollbarWidget * scrollbar );
        void paint();
        bool mousePressed( SDL_MouseButtonEvent * evt );
        bool mouseReleased( SDL_MouseButtonEvent * evt );
        void updateWidget();
        
};


#endif
