#include "Splash.h"

	// constructor
Splash::Splash()
{
	// sets size to 75% of screen area
	SetSize(75);
	
	// 100 ms for a timer tick
	tickTime = 20;
	
	BackPaint();
}

void Splash::ChildMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags)
{
	if(event == LEFTDOWN || event == RIGHTDOWN)
		WhenCloseClick();
}

Image Splash::MouseEvent(int event, Point p, int zdelta, dword keyflags)
{
	if(event == CURSORIMAGE)
		return Ctrl::MouseEvent(event, p, zdelta, keyflags);
	ChildMouseEvent(NULL, event, p, zdelta, keyflags);
	return Image();
}

// sets max size of splash ctrl
// defaults to 50% of screen size
Splash &Splash::SetSize(int screenPercent)
{
	percentSize = screenPercent;
	return *this;
}

// image setting
Splash &Splash::SetImage(Image const &img)
{
	image = img;
	return *this;
}

// sets tick time
Splash &Splash::SetTickTime(int time)
{
	tickTime = time;
	return *this;
}

void Splash::Paint(Draw &w)
{
	SetSurface(w, GetView(), scaledImage, scaledImage.GetSize(), Point(0, 0));
}

// fade in/out -- returns true if ok, false if already busy
void Splash::FadeIn(int steps)
{
	if(IsOpen())
		Close();

	// gets true splash size on screen percent one
	// depending on splash image aspect in order to NOT crop it
	splashSize = GetPrimaryWorkArea().GetSize();
	splashSize.cx = iscale(splashSize.cx, percentSize, 100);
	splashSize.cy = iscale(splashSize.cy, percentSize, 100);
	Size imgSize = image.GetSize();
	double imgRatio = (double)imgSize.cx / (double)imgSize.cy;
	if(splashSize.cy * imgRatio < splashSize.cx)
		splashSize.cx = (int)(splashSize.cy * imgRatio);
	else
		splashSize.cy = (int)(splashSize.cx / imgRatio);
	
	// prepares a scaled image copy
	ImageDraw dw(splashSize);
	dw.DrawImage(0, 0, splashSize.cx, splashSize.cy, image);
	scaledImage = dw;
	
	Size ss = GetPrimaryWorkArea().GetSize();
	SetRect(0, 0, 1, 1);

	PopUp(NULL, false, false, true, true);
	Show();
	for(int i = 0; i < steps; i++)
	{
		Size sz(iscale(splashSize.cx, i, steps), iscale(splashSize.cy, i, steps));
		SetRect((ss.cx - sz.cx) / 2, (ss.cy - sz.cy) / 2, sz.cx, sz.cy);
		Ctrl::ProcessEvents();
		Sleep(tickTime);
	}
}

void Splash::FadeOut(int steps)
{
	if(!IsOpen())
		return;
	if(HasChild(&versionPane))
		RemoveChild(&versionPane);
	Size ss = GetPrimaryWorkArea().GetSize();
	for(int i = steps-1; i >= 0; i--)
	{
		Size sz(iscale(splashSize.cx, i, steps), iscale(splashSize.cy, i, steps));
		SetRect((ss.cx - sz.cx) / 2, (ss.cy - sz.cy) / 2, sz.cx, sz.cy);
		Ctrl::ProcessEvents();
		Sleep(tickTime);
	}
	Close();
	
	scaledImage.Clear();
}

// empirically found....
#define QTF_SCALE_FACTOR 120

void Splash::ShowVersion(String const &version)
{
	versionPane.SetQTF(version);
	versionPane.NoSb();
	
	// get sizes
	int cx = versionPane.GetWidth();
	int cy = versionPane.GetHeight(cx);
	Add(versionPane.RightPos(50, cx).TopPos(splashSize.cy / 3, cy));
}

void Splash::HideVersion(void)
{
	RemoveChild(&versionPane);
}

// about box behaviour
void Splash::AboutBox(String const &cont, int inSteps, int outSteps)
{
	FadeIn(inSteps);
	contents.SetQTF(cont);
	contents.NoSb();
	int cx = contents.GetWidth();
	int cy = contents.GetHeight(cx);
	Add(contents.RightPos(50, cx).TopPos(splashSize.cy / 3, cy));

	WhenCloseClick = THISBACK1(AboutClose, outSteps);
	GetMainWindow()->Disable();
}

// close aboutbox handle
void Splash::AboutClose(int steps)
{
	GetMainWindow()->Enable();
	RemoveChild(&contents);
	FadeOut(steps);
}
