//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================


#include "VGUI_ScrollBar2.h"
#include "VGUI_Slider2.h"
#include "vgui_loadtga.h"

#include<VGUI_IntChangeSignal.h>
#include<VGUI_Button.h>
#include<VGUI_ActionSignal.h>
#include<VGUI_LineBorder.h>

using namespace vgui;


namespace
{
class FooDefaultScrollBarIntChangeSignal : public IntChangeSignal
{
public:
	FooDefaultScrollBarIntChangeSignal(ScrollBar2* scrollBar)
	{
		_scrollBar=scrollBar;
	}
	virtual void intChanged(int value,Panel* panel)
	{
		_scrollBar->fireIntChangeSignal();
	}
protected:
	ScrollBar2* _scrollBar;
};

class FooDefaultButtonSignal : public ActionSignal
{
public:
	ScrollBar2* _scrollBar;
	int        _buttonIndex;
public:
	FooDefaultButtonSignal(ScrollBar2* scrollBar,int buttonIndex)
	{
		_scrollBar=scrollBar;
		_buttonIndex=buttonIndex;
	}
public:
	virtual void actionPerformed(Panel* panel)
	{
		_scrollBar->doButtonPressed(_buttonIndex);
	}
};

}

//-----------------------------------------------------------------------------
// Purpose: Default scrollbar button
//			Draws in new scoreboard style
//-----------------------------------------------------------------------------
class ScrollBarButton : public Button
{
private:
	LineBorder m_Border;

public:
	ScrollBarButton(const char *filename, int x, int y, int wide, int tall) : m_Border(Color(60, 60, 60, 0)), Button("", x, y, wide, tall)
	{
		Image *image = vgui_LoadTGA(filename);
		if (image)
		{
			image->setColor(Color(140, 140, 140, 0));
			setImage(image);
		}

		setBorder(&m_Border);
	}

	virtual void paintBackground()
	{
		int wide,tall;
		getPaintSize(wide,tall);

		// fill the background
		drawSetColor(0, 0, 0, 0);
		drawFilledRect(0, 0, wide, tall);
	}
};




//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input  : x - 
//			y - 
//			wide - 
//			tall - 
//			vertical - 
//-----------------------------------------------------------------------------
ScrollBar2::ScrollBar2(int x,int y,int wide,int tall,bool vertical) : Panel(x,y,wide,tall)
{
	_slider=null;
	_button[0]=null;
	_button[1]=null;
	
	if(vertical)
	{
		setSlider(new Slider2(0,wide-1,wide,(tall-(wide*2))+2,true));
		setButton(new ScrollBarButton("gfx/vgui/arrowup.tga",0,0,wide,wide),0);
		setButton(new ScrollBarButton("gfx/vgui/arrowdown.tga",0,tall-wide,wide,wide),1);
	}
	else
	{
		// untested code
		setSlider(new Slider2(tall,0,wide-(tall*2),tall,false));
		setButton(new ScrollBarButton("gfx/vgui/320_arrowlt.tga",0,0,tall+1,tall+1),0);
		setButton(new ScrollBarButton("gfx/vgui/320_arrowrt.tga",wide-tall,0,tall+1,tall+1),1);
	}

	setPaintBorderEnabled(true);
	setPaintBackgroundEnabled(true);
	setPaintEnabled(true);
	setButtonPressedScrollValue(15);

	validate();
 }

void ScrollBar2::setSize(int wide,int tall)
{
	Panel::setSize(wide,tall);

	if(_slider==null)
	{
		return;
	}

	if(_button[0]==null)
	{
		return;
	}

	if(_button[1]==null)
	{
		return;
	}

	getPaintSize(wide,tall);

	if(_slider->isVertical())
	{
		_slider->setBounds(0,wide,wide,tall-(wide*2));
		//_slider->setBounds(0,0,wide,tall);
		_button[0]->setBounds(0,0,wide,wide);
		_button[1]->setBounds(0,tall-wide,wide,wide);
	}
	else
	{
		_slider->setBounds(tall,0,wide-(tall*2),tall);
		//_slider->setBounds(0,0,wide,tall);
		_button[0]->setBounds(0,0,tall,tall);
		_button[1]->setBounds((wide-tall),0,tall,tall);
	}
}

void ScrollBar2::performLayout()
{
}

void ScrollBar2::setValue(int value)
{
	_slider->setValue(value);
}

int ScrollBar2::getValue()
{
	return _slider->getValue();
}

void ScrollBar2::addIntChangeSignal(IntChangeSignal* s)
{
	_intChangeSignalDar.putElement(s);
	_slider->addIntChangeSignal(new FooDefaultScrollBarIntChangeSignal(this));
}

void ScrollBar2::setRange(int min,int max)
{
	_slider->setRange(min,max);
}

void ScrollBar2::fireIntChangeSignal()
{
	for(int i=0;i<_intChangeSignalDar.getCount();i++)
	{
		_intChangeSignalDar[i]->intChanged(_slider->getValue(),this);
	}
}

bool ScrollBar2::isVertical()
{
	return _slider->isVertical();
}

bool ScrollBar2::hasFullRange()
{
	return _slider->hasFullRange();
}

//LEAK: new and old slider will leak
void ScrollBar2::setButton(Button* button,int index)
{
	if(_button[index]!=null)
	{
		removeChild(_button[index]);
	}
	_button[index]=button;
	addChild(_button[index]);

	_button[index]->addActionSignal(new FooDefaultButtonSignal(this,index));

	validate();

	//_button[index]->setVisible(false);
}

Button* ScrollBar2::getButton(int index)
{
	return _button[index];
}

//LEAK: new and old slider will leak
void ScrollBar2::setSlider(Slider2 *slider)
{
	if(_slider!=null)
	{
		removeChild(_slider);
	}
	_slider=slider;
	addChild(_slider);

	_slider->addIntChangeSignal(new FooDefaultScrollBarIntChangeSignal(this));

	validate();
}

Slider2 *ScrollBar2::getSlider()
{
	return _slider;
}

void ScrollBar2::doButtonPressed(int buttonIndex)
{
	if(buttonIndex==0)
	{
		_slider->setValue(_slider->getValue()-_buttonPressedScrollValue);
	}
	else
	{
		_slider->setValue(_slider->getValue()+_buttonPressedScrollValue);
	}

}

void ScrollBar2::setButtonPressedScrollValue(int value)
{
	_buttonPressedScrollValue=value;
}

void ScrollBar2::setRangeWindow(int rangeWindow)
{
	_slider->setRangeWindow(rangeWindow);
}

void ScrollBar2::setRangeWindowEnabled(bool state)
{
	_slider->setRangeWindowEnabled(state);
}

void ScrollBar2::validate()
{
	if(_slider!=null)
	{
		int buttonOffset=0;

		for(int i=0;i<2;i++)
		{
			if(_button[i]!=null)
			{
				if(_button[i]->isVisible())
				{
					if(_slider->isVertical())
					{					
						buttonOffset+=_button[i]->getTall();
					}
					else
					{
						buttonOffset+=_button[i]->getWide();
					}
				}
			}
		}

		_slider->setButtonOffset(buttonOffset);
	}

	int wide,tall;
	getSize(wide,tall);
	setSize(wide,tall);
}