#include "BoardManager.h"

#include "AVersion.h"
#include "Settings.h"
#include "Images.h"

// constructor
BoardManagerPane::BoardManagerPane(Platform &platform) : _platform(platform)
{
	CtrlLayout(*this);
	textBox.NoSb();
	
	_deltaHeight = GetSize().cy - textBox.GetSize().cy;
	actionButton <<= THISBACK(actionHandlerCb);
	versionDrop <<= THISBACK1(FillPane, false);
}

// destructor
BoardManagerPane::~BoardManagerPane()
{
}

// install/remove/update button handler
void BoardManagerPane::actionHandlerCb(void)
{
	// find the requested action
	String sel = versionDrop.Get();
	if(_platform.IsInstalled())
	{
		String inst = _platform.GetInstalledVersion();
		if(inst == sel)
		{
			// remove is requested
			_platform.Remove();
		}
		else
		{
			// upgrade or downgrade
			_platform.Install(sel);
		}
	}
	else
	{
		// install
		_platform.Install(sel);
	}
	FillPane(false);
	Settings.RefreshInstalled();
}

// sets background color
void BoardManagerPane::BackColor(Upp::Color const &c)
{
	Background(c);
	textBox.Background(c);
}

// fill pane from platform
void BoardManagerPane::FillPane(bool fillDrop)
{
	ArrayMap<String, PlatformVersion> &versions = _platform.GetVersions();
	bool isInstalled = _platform.IsInstalled();
	if(fillDrop)
	{
		versionDrop.Clear();
		int installed = -1;
		for(int iVersion = 0; iVersion < versions.GetCount(); iVersion++)
		{
			String ver = versions.GetKey(iVersion);
			versionDrop.Add(ver);
			if(isInstalled && ver == _platform.GetInstalledVersion())
				installed = iVersion;
		}
		if(installed >= 0)
			versionDrop.SetIndex(installed);
		else
			versionDrop.SetIndex(0);
	}
	else
	{
/*
		if(isInstalled)
			versionDrop.SetIndex(versionDrop.FindKey(_platform.GetInstalledVersion()));
*/
	}
	
	// fill text area
	Zoom z = GetRichTextStdScreenZoom();
	textBox.SetZoom(z);
	PlatformVersion &version = _platform.GetVersions().Get(versionDrop.Get());
	String text = String("[1 [* ") + _platform.GetName() + "]" + t_(" by ") + "[* " + _platform.GetPackage().GetMaintainer() + "]";
	if(_platform.IsInstalled())
		text << "[/* __" << t_("Version") << "_" << _platform.GetInstalledVersion() << "_" << t_("INSTALLED") << "]";
	text << "&";
	text << t_("Boards included in this package:") << "&";
	Vector<String> const &boards = version.GetProvidedBoards();
	for(int iBoard = 0; iBoard < boards.GetCount(); iBoard++)
		text << boards[iBoard] << ", ";
	text = text.Left(text.GetCount() - 2);
	text << "&";
	text += "]";
	textBox.SetQTF(text);
	
	// fill button text
	if(_platform.IsInstalled())
	{
		String inst(_platform.GetInstalledVersion());
		String sel(versionDrop.Get());
		if(inst == sel)
			actionButton.SetLabel(t_("Remove"));
		else if(AVersion(inst) < AVersion(sel))
			actionButton.SetLabel(t_("Update"));
		else
			actionButton.SetLabel(t_("Downgrade"));
	}
	else
		actionButton.SetLabel(t_("Install"));
}
	
///////////////////////////////////////////////////////////////////////////////

// adjust layout
void BoardManager::Layout(void)
{
	// setup scrollbar total size
	scrollBar.SetPage(panesArea.GetSize().cy);

	int _totalPanesHeight = 0;
	for(int iPane = 0; iPane < _panes.GetCount(); iPane++)
	{
		BoardManagerPane &pane = _panes[iPane];
		_totalPanesHeight += pane.GetSize().cy;
	}
	scrollBar.SetTotal(_totalPanesHeight);

	int y = -scrollBar.Get();
	for(int iPane = 0; iPane < _panes.GetCount(); iPane++)
	{
		BoardManagerPane &pane = _panes[iPane];

		// adjust pane height to contain all text
		Zoom z = GetRichTextStdScreenZoom();
		int paneHeight = pane.textBox.Get().GetHeight(z, pane.textBox.GetSize().cx)  + pane.GetDeltaHeight();
		pane.SetRectY(pane.GetRect().top, paneHeight);

		pane.HSizePos();
		pane.TopPos(y, paneHeight);
		y += paneHeight;
	}
}

// constructor
BoardManager::BoardManager()
{
	CtrlLayout(*this);
	Title(t_("Board manager"));
	Icon(FishIDEImg::Board());
	Sizeable();
	closeBtn << Breaker(IDCLOSE);
	
	// fill panes with text from platforms
	int iColor = 0;
	for(int iPackage = 0; iPackage < Packages.GetCount(); iPackage++)
	{
		Package &package = Packages[iPackage];
		Array<Platform> &platforms = package.GetPlatforms();
		for(int iPlatform = 0; iPlatform < platforms.GetCount(); iPlatform++)
		{
			Platform &platform = platforms[iPlatform];
			BoardManagerPane &pane = _panes.Add(new BoardManagerPane(platform));
			pane.FillPane(true);
			panesArea.Add(pane);
			pane.BackColor((iColor++ % 2) ? Color(236, 241, 241) : Color(218, 227, 227));
		}
	}
	
	// force layout update to adjust rich text
	Layout();
	scrollBar.WhenScroll = THISBACK(Layout);
}

// destructor
BoardManager::~BoardManager()
{
}

void BoardManager::MouseWheel(Point, int zdelta, dword)
{
	scrollBar.Wheel(zdelta * StdFont().Info().GetHeight() / 2);
}

bool BoardManager::Key(dword key, int)
{
	return scrollBar.VertKey(key);
}

void BoardManager::ChildMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags)
{
	if((event & ACTION) == MOUSEWHEEL)
		MouseWheel(p, zdelta, keyflags);
}

