#include "seekbar.h"
#include "common.h"

SeekBar::SeekBar() : Widget()
{
	// Set default state
	bgSprite = NULL;
	bgImage = NULL;
	
	dragSprite = NULL;
	dragImage = NULL;
	
	// set correct control
	state = 0;
	dragStat = 0;
}

SeekBar::~SeekBar()
{
	// Free images
	if(bgSprite) { delete bgSprite; }
	if(bgImage) { delete bgImage; }
	
	if(dragSprite) { delete dragSprite; }
	if(dragImage) { delete dragImage; }
}

void SeekBar::draw()
{
	// Grab location including parent
	Rect dLoc = getDimensions();
	
	// Ensure its been set up
	if(!bgSprite)
	{
		// It hasn't
		reskin();
	}
	
	// Calculate position
	int length = sound.getSoundLength();
	int pos = sound.getSoundPosition();
	
	// Calculate the movable area
	int spread = dLoc.width - ((dragImage->GetWidth()) / 3);
	
	// Set correct sprite state (nothing, hover, or clicked)
	int tState = state;
	if(tState > 2) { tState = 2; }
	
	// Set actual image state
	dragSprite->SetFrame(tState);
	
	// Create a window
	LayerManager manager(2);
	
	// Only append if the file can seek
	if(length > 0)
	{
		// Calculate position
		int xpos;
		
		if(dragStat)
		{
			// From cursor
			xpos = dragLoc - (dragImage->GetWidth() / 6);
			
			// Limit
			if(xpos < 0) { xpos = 0; }
			if(xpos > spread) { xpos = spread; }
		}
		else
		{
			// From current file
			xpos = (int)((double)spread * ((double)pos / (double)length));
		}
		
		// Ensure handle appears in the proper place
		dragSprite->SetPosition(dLoc.x + xpos, dLoc.y + (dLoc.height / 2) - (dragImage->GetHeight() / 2));
		
		// Append label to window
		manager.Append(dragSprite);
	}
	
	// Ensure bg appears in the proper place
	bgSprite->SetPosition(dLoc.x, dLoc.y);
	
	// Append label to window
	manager.Append(bgSprite);
	
	// Draw to screen
	manager.Draw(settingsManager.getOffsetX(), settingsManager.getOffsetY());
}

void SeekBar::reskin()
{
	// Free images
	if(bgSprite) { delete bgSprite; }
	if(bgImage) { delete bgImage; }
	
	if(dragSprite) { delete dragSprite; }
	if(dragImage) { delete dragImage; }
	
	// First do the background
	char tPath[256];
	char tGraphic[256];
	
	// Grab path to theme on sd card
	windowManager.getThemePath(tPath);
	
	// Get image path
	windowManager.getString("SeekBar.Background.FileName", tGraphic);
	
	// Concatenate urls
	strcat(tPath, tGraphic);
	
	// Load the image
	bgImage = new Image();
	
	if(bgImage->LoadImage(tPath) != IMG_LOAD_ERROR_NONE)
	{
		// Try loading from default
		if(bgImage->LoadImage(DATAPATH "images/seekbg.png") != IMG_LOAD_ERROR_NONE) exit(0);
	}
	
	// Grab new sprite
	bgSprite = new Sprite();
	bgSprite->SetImage(bgImage);
	
	// Set size based on this
	_rect.width = bgImage->GetWidth();
	_rect.height = bgImage->GetHeight();
	
	// Grab path to theme on sd card
	windowManager.getThemePath(tPath);
	
	// Get image path
	windowManager.getString("SeekBar.Handle.FileName", tGraphic);
	
	// Concatenate urls
	strcat(tPath, tGraphic);
	
	// Load the image
	dragImage = new Image();
	
	if(dragImage->LoadImage(tPath) != IMG_LOAD_ERROR_NONE)
	{
		// Try loading from default
		if(dragImage->LoadImage(DATAPATH "images/seekhandle.png") != IMG_LOAD_ERROR_NONE) exit(0);
	}
	
	// Grab new sprite
	dragSprite = new Sprite();
	dragSprite->SetImage(dragImage, (dragImage->GetWidth()) / 3, dragImage->GetHeight());
}

void SeekBar::cursorDown(int x, int y, Action a)
{
	// See if we have + or - to seek
	if(a == BUTTON_PLUS)
	{
		// Get sound length and position
		int length = sound.getSoundLength();
		
		// No seeking if no length
		if(length < 0) { return; }
		
		int pos = sound.getSoundPosition() + 5;
		
		// Limit
		if(pos > length) { pos = length; }
		
		// Seek
		sound.setSoundPosition(pos);
		return;
	}
	else if(a == BUTTON_MINUS)
	{
		// Get sound length and position
		int length = sound.getSoundLength();
		
		// No seeking if no length
		if(length < 0) { return; }
		
		// Get sound position
		int pos = sound.getSoundPosition() - 5;
		
		// Limit
		if(pos < 0) { pos = 0; }
		
		// Seek
		sound.setSoundPosition(pos);
		return;
	}
	
	// Only primary click
	if(a != BUTTON_PRIMARY) { return; }
	
	// Move image
	dragLoc = x;
	_dragging = true;
	dragStat = 1;
	
	// Add clicked state
	state += 2;
}

void SeekBar::cursorMove(int x, int y)
{
	// Dragging?
	if(state >= 2) { dragLoc = x; }
	
	// If we dragged too far away, don't let drag happen
	if(_dragging)
	{
		if(x < -40 || y < -40 || x > _rect.width + 40 || y > _rect.height + 40)
		{
			dragStat = 0;
		}
		else
		{
			dragStat = 1;
		}
	}
	
	// Already set hover?
	if(state & 1) { return; }
	
	// Set hover
	state++;
}

void SeekBar::cursorUp(int x, int y, Action a)
{
	// Only primary click
	if(a != BUTTON_PRIMARY) { return; }
	
	// Move image
	dragLoc = x;
	_dragging = false;
	
	// Get sound length
	int length = sound.getSoundLength();
	
	if(length > 0 && dragStat)
	{	
		// Calculate seek spread
		int spread = _rect.width - ((dragImage->GetWidth()) / 3);
		
		// Calculate where left of drag image is
		int xpos = dragLoc - (dragImage->GetWidth() / 6);
		
		// Limit
		if(xpos < 0) { xpos = 0; }
		if(xpos > spread) { xpos = spread; }
		
		// Figure out new seconds
		int seconds = (int)((double)length * ((double)xpos / (double)spread));
		
		// Seek
		sound.setSoundPosition(seconds);
	}
	
	// Remove clicked state
	state -=2;
	dragStat = 0;
	dragLoc = 0;
	
	// Ensure we didn't let go after going out of bounds
	if(state < 0) { state = 0; }
}

void SeekBar::cursorOut()
{
	// Unset all
	state = 0;
	dragStat = 0;
	dragLoc = 0;
}
