// Convert Point size to Pixel size (Useful in gdi.Font() and such)
function Point2Pixel(pt, dpi) {
	return (pt * dpi / 72);
}

function RGBA(r, g, b, a) {
	return ((a << 24) | (r << 16) | (g << 8) | (b));
}

function RGB(r, g, b) {
	return (0xff000000 | (r << 16) | (g << 8) | (b));
}

function getAlpha(color) {
	return ((color >> 24) & 0xff);
}

function getRed(color) {
	return ((color >> 16) & 0xff);
}

function getGreen(color) {
	return ((color >> 8) & 0xff);
}

function getBlue(color) {
	return (color & 0xff);
}

function setAlpha(color, a) {
	return ((color & 0x00ffffff) | (a << 24));
}

function setRed(color, r) {
	return ((color & 0xff00ffff) | (r << 16));
}

function setGreen(color, g) {
	return ((color & 0xffff00ff) | (g << 8));
}

function setBlue(color, b) {
	return ((color & 0xffffff00) | b);
}

// Helper function for DrawString() and MeasureString()
// args: h_align, v_align, trimming, flags
function StringFormat() {
	var h_align = 0, v_align = 0, trimming = 0, flags = 0;
	switch (arguments.length)
	{
	// fall-thru
	case 4:
		flags = arguments[3];
	case 3:
		trimming = arguments[2];
	case 2:
		v_align = arguments[1];
	case 1:
		h_align = arguments[0];
		break;
	default:
		return 0;
	}
	return ((h_align << 28) | (v_align << 24) | (trimming << 20) | flags);
}

// Based on human hearing curve
// 0 <= pos <= 1
// return a value value: -100 <= vol <= 0
function pos2vol(pos) {
	 return 50 * Math.log(0.99 * pos + 0.01) / Math.LN10;
}

// Inverse function of pos2vol()
function vol2pos(v){
	 return (Math.pow(10, v / 50) - 0.01) / 0.99;
}

// pre-calculated colors
var Colors = {
	AliceBlue			: 0xFFF0F8FF,
	AntiqueWhite		 : 0xFFFAEBD7,
	Aqua				 : 0xFF00FFFF,
	Aquamarine		   : 0xFF7FFFD4,
	Azure				: 0xFFF0FFFF,
	Beige				: 0xFFF5F5DC,
	Bisque			   : 0xFFFFE4C4,
	Black				: 0xFF000000,
	BlanchedAlmond	   : 0xFFFFEBCD,
	Blue				 : 0xFF0000FF,
	BlueViolet		   : 0xFF8A2BE2,
	Brown				: 0xFFA52A2A,
	BurlyWood			: 0xFFDEB887,
	CadetBlue			: 0xFF5F9EA0,
	Chartreuse		   : 0xFF7FFF00,
	Chocolate			: 0xFFD2691E,
	Coral				: 0xFFFF7F50,
	CornflowerBlue	   : 0xFF6495ED,
	Cornsilk			 : 0xFFFFF8DC,
	Crimson			  : 0xFFDC143C,
	Cyan				 : 0xFF00FFFF,
	DarkBlue			 : 0xFF00008B,
	DarkCyan			 : 0xFF008B8B,
	DarkGoldenrod		: 0xFFB8860B,
	DarkGray			 : 0xFFA9A9A9,
	DarkGreen			: 0xFF006400,
	DarkKhaki			: 0xFFBDB76B,
	DarkMagenta		  : 0xFF8B008B,
	DarkOliveGreen	   : 0xFF556B2F,
	DarkOrange		   : 0xFFFF8C00,
	DarkOrchid		   : 0xFF9932CC,
	DarkRed			  : 0xFF8B0000,
	DarkSalmon		   : 0xFFE9967A,
	DarkSeaGreen		 : 0xFF8FBC8B,
	DarkSlateBlue		: 0xFF483D8B,
	DarkSlateGray		: 0xFF2F4F4F,
	DarkTurquoise		: 0xFF00CED1,
	DarkViolet		   : 0xFF9400D3,
	DeepPink			 : 0xFFFF1493,
	DeepSkyBlue		  : 0xFF00BFFF,
	DimGray			  : 0xFF696969,
	DodgerBlue		   : 0xFF1E90FF,
	Firebrick			: 0xFFB22222,
	FloralWhite		  : 0xFFFFFAF0,
	ForestGreen		  : 0xFF228B22,
	Fuchsia			  : 0xFFFF00FF,
	Gainsboro			: 0xFFDCDCDC,
	GhostWhite		   : 0xFFF8F8FF,
	Gold				 : 0xFFFFD700,
	Goldenrod			: 0xFFDAA520,
	Gray				 : 0xFF808080,
	Green				: 0xFF008000,
	GreenYellow		  : 0xFFADFF2F,
	Honeydew			 : 0xFFF0FFF0,
	HotPink			  : 0xFFFF69B4,
	IndianRed			: 0xFFCD5C5C,
	Indigo			   : 0xFF4B0082,
	Ivory				: 0xFFFFFFF0,
	Khaki				: 0xFFF0E68C,
	Lavender			 : 0xFFE6E6FA,
	LavenderBlush		: 0xFFFFF0F5,
	LawnGreen			: 0xFF7CFC00,
	LemonChiffon		 : 0xFFFFFACD,
	LightBlue			: 0xFFADD8E6,
	LightCoral		   : 0xFFF08080,
	LightCyan			: 0xFFE0FFFF,
	LightGoldenrodYellow : 0xFFFAFAD2,
	LightGray			: 0xFFD3D3D3,
	LightGreen		   : 0xFF90EE90,
	LightPink			: 0xFFFFB6C1,
	LightSalmon		  : 0xFFFFA07A,
	LightSeaGreen		: 0xFF20B2AA,
	LightSkyBlue		 : 0xFF87CEFA,
	LightSlateGray	   : 0xFF778899,
	LightSteelBlue	   : 0xFFB0C4DE,
	LightYellow		  : 0xFFFFFFE0,
	Lime				 : 0xFF00FF00,
	LimeGreen			: 0xFF32CD32,
	Linen				: 0xFFFAF0E6,
	Magenta			  : 0xFFFF00FF,
	Maroon			   : 0xFF800000,
	MediumAquamarine	 : 0xFF66CDAA,
	MediumBlue		   : 0xFF0000CD,
	MediumOrchid		 : 0xFFBA55D3,
	MediumPurple		 : 0xFF9370DB,
	MediumSeaGreen	   : 0xFF3CB371,
	MediumSlateBlue	  : 0xFF7B68EE,
	MediumSpringGreen	: 0xFF00FA9A,
	MediumTurquoise	  : 0xFF48D1CC,
	MediumVioletRed	  : 0xFFC71585,
	MidnightBlue		 : 0xFF191970,
	MintCream			: 0xFFF5FFFA,
	MistyRose			: 0xFFFFE4E1,
	Moccasin			 : 0xFFFFE4B5,
	NavajoWhite		  : 0xFFFFDEAD,
	Navy				 : 0xFF000080,
	OldLace			  : 0xFFFDF5E6,
	Olive				: 0xFF808000,
	OliveDrab			: 0xFF6B8E23,
	Orange			   : 0xFFFFA500,
	OrangeRed			: 0xFFFF4500,
	Orchid			   : 0xFFDA70D6,
	PaleGoldenrod		: 0xFFEEE8AA,
	PaleGreen			: 0xFF98FB98,
	PaleTurquoise		: 0xFFAFEEEE,
	PaleVioletRed		: 0xFFDB7093,
	PapayaWhip		   : 0xFFFFEFD5,
	PeachPuff			: 0xFFFFDAB9,
	Peru				 : 0xFFCD853F,
	Pink				 : 0xFFFFC0CB,
	Plum				 : 0xFFDDA0DD,
	PowderBlue		   : 0xFFB0E0E6,
	Purple			   : 0xFF800080,
	Red				  : 0xFFFF0000,
	RosyBrown			: 0xFFBC8F8F,
	RoyalBlue			: 0xFF4169E1,
	SaddleBrown		  : 0xFF8B4513,
	Salmon			   : 0xFFFA8072,
	SandyBrown		   : 0xFFF4A460,
	SeaGreen			 : 0xFF2E8B57,
	SeaShell			 : 0xFFFFF5EE,
	Sienna			   : 0xFFA0522D,
	Silver			   : 0xFFC0C0C0,
	SkyBlue			  : 0xFF87CEEB,
	SlateBlue			: 0xFF6A5ACD,
	SlateGray			: 0xFF708090,
	Snow				 : 0xFFFFFAFA,
	SpringGreen		  : 0xFF00FF7F,
	SteelBlue			: 0xFF4682B4,
	Tan				  : 0xFFD2B48C,
	Teal				 : 0xFF008080,
	Thistle			  : 0xFFD8BFD8,
	Tomato			   : 0xFFFF6347,
	Transparent		  : 0x00FFFFFF,
	Turquoise			: 0xFF40E0D0,
	Violet			   : 0xFFEE82EE,
	Wheat				: 0xFFF5DEB3,
	White				: 0xFFFFFFFF,
	WhiteSmoke		   : 0xFFF5F5F5,
	Yellow			   : 0xFFFFFF00,
	YellowGreen		  : 0xFF9ACD32
};

function button(x, y, w, h, img_src, fn, tiptext) {
	this.paint = function (gr) {
		this.img && gr.DrawImage(this.img, this.x, this.y, this.w, this.h, 0, 0, this.img.Width, this.img.Height);
	}
	
	this.trace = function (x, y) {
		return x > this.x && x < this.x + this.w && y > this.y && y < this.y + this.h;
	}
	
	this.lbtn_up = function (x, y) {
		this.fn && this.fn(x, y);
	}
	
	this.cs = function (s) {
		if (s == "hover") {
			this.img = this.img_hover;
			tt(this.tiptext);
		} else {
			this.img = this.img_normal;
		}
		window.RepaintRect(this.x, this.y, this.w, this.h);
	}
	
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.fn = fn;
	this.tiptext = tiptext;
	this.img_normal = gdi.Image(img_src.normal);
	this.img_hover = img_src.hover ? gdi.Image(img_src.hover) : this.img_normal;
	this.img = this.img_normal;
}

function buttons() {
	this.paint = function (gr) {
		for (var i in this.buttons) {
			this.buttons[i].paint(gr);
		}
	}
	
	this.move = function (x, y) {
		var temp_btn = null;
		for (var i in this.buttons) {
			if (this.buttons[i].trace(x, y))
				temp_btn = i;
		}
		if (this.btn == temp_btn)
			return this.btn;
		if (this.btn)
			this.buttons[this.btn].cs("normal");
		if (temp_btn)
			this.buttons[temp_btn].cs("hover");
		else
			tt("");
		this.btn = temp_btn;
		return this.btn;
	}
	
	this.leave = function () {
		if (this.btn) {
			tt("");
			this.buttons[this.btn].cs("normal");
		}
		this.btn = null;
	}
	
	this.lbtn_up = function (x, y) {
		if (this.btn) {
			this.buttons[this.btn].lbtn_up(x, y);
			return true;
		} else {
			return false;
		}
	}
	
	this.buttons = {};
	this.btn = null;
}

function seekbar(x, y, w, h) {
	this.playback_seek = function () {
		window.RepaintRect(this.x - 100, this.y, this.w + 200, this.h);
	}
	
	this.playback_stop = function () {
		this.playback_seek();
	}
	
	this.trace = function (x, y) {
		var m = this.drag ? 200 : 0;
		return x > this.x - m && x < this.x + this.w + m && y > this.y - m && y < this.y + this.h + m;
	}
	
	this.wheel = function (s) {
		if (this.trace(this.mx, this.my)) {
			switch (true) {
			case !fb.IsPlaying:
			case fb.PlaybackLength <= 0:
				break;
			case fb.PlaybackLength < 60:
				fb.PlaybackTime += s * 5;
				break;
			case fb.PlaybackLength < 600:
				fb.PlaybackTime += s * 10;
				break;
			default:
				fb.PlaybackTime += s * 60;
				break;
			}
			tt("");
			return true;
		} else {
			return false;
		}
	}
	
	this.move = function (x, y) {
		this.mx = x;
		this.my = y;
		if (this.trace(x, y)) {
			if (fb.IsPlaying && fb.PlaybackLength > 0) {
				x -= this.x;
				this.drag_seek = x < 0 ? 0 : x > this.w ? 1 : x / this.w;
				tt(utils.FormatDuration(fb.PlaybackLength * this.drag_seek));
				if (this.drag)
					this.playback_seek();
			}
			this.hover = true;
			return true;
		} else {
			if (this.hover)
				tt("");
			this.hover = false;
			this.drag = false;
			return false;
		}
	}
	
	this.lbtn_down = function (x, y) {
		if (this.trace(x, y)) {
			if (fb.IsPlaying && fb.PlaybackLength > 0)
				this.drag = true;
			return true;
		} else {
			return false;
		}
	}
	
	this.lbtn_up = function (x, y) {
		if (this.trace(x, y)) {
			if (this.drag) {
				this.drag = false;
				fb.PlaybackTime = fb.PlaybackLength * this.drag_seek;
			}
			return true;
		} else {
			return false;
		}
	}
	
	this.pos = function () {
		return Math.ceil(this.w * (this.drag ? this.drag_seek : fb.PlaybackTime / fb.PlaybackLength));
	}
	
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.mx = 0;
	this.my = 0;
	this.hover = false;
	this.drag = false;
	this.drag_seek = 0;
	window.SetInterval(function () {
		if (fb.IsPlaying && !fb.IsPaused && fb.PlaybackLength > 0)
			on_playback_seek();
	}, 150);
}

function tt(value) {
	if (tooltip.Text != value) {
		tooltip.Text = value;
		tooltip.Activate();
	}
}
