/* -----------------------------------------------------------------------------
	myQuiltGenie - global functions - scripts
----------------------------------------------------------------------------- */
var imgs	= [];

/* -----------------------------------------------------------------------------
	format_fraction(num[, type]);
		num		NUMBER
		type	INTEGER		4=quarters (DEFAULT) | 8=eigths
		RETURN (STRING) HTML fraction string
----------------------------------------------------------------------------- */
function format_fraction(num, type) 
{
	var integer, 
		denominator, 
		numerator;
	if ((num % 1) > 0) 
	{
		integer		= (num <= 1) ? '' : Math.floor(num);
		denominator	= (type == 8) ? type : 4;
		numerator	= Math.ceil((num % 1) / (1 / denominator));
		if (numerator >= denominator) 
		{
			return (integer + 1);
		}
		else if ((numerator % 2) === 0) 
		{
			denominator	/= 2;
			numerator	/= 2;
			if ((numerator % 2) === 0) 
			{
				denominator	/= 2;
				numerator	/= 2;
			}
		}
		return integer + '<span style="font-size: 80%; vertical-align: middle; letter-spacing: -2px"><sup>' + numerator +
			 '</sup>/<sub>' + denominator + '</sub></span>';
	}
	else 
	{
		return '' + num + '';
	}
}

/* -----------------------------------------------------------------------------
	calc_strips(height[, num_pieces[, width[, diag]]]);
	**** array of height & num_pieces works best with smaller height first ****
		height		MIXED		number|array of numbers - piece length
		num_pieces	MIXED		integer|array of number of pieces
		width		NUMBER		strip width
		diag		BOOLEAN		piece on diagonal: false (DEFAULT) | true
				REQUIRED fab_width
		RETURN (INTEGER) number of strips
----------------------------------------------------------------------------- */
function calc_strips(height, num_pieces, width, diag) 
{
	var num_strips			= 0, 
		pieces_per_strip	= 0, 
		connect 			= (diag) ? ((width * 2) + 0.5) : 0.5, 
		i, 
		inches				= '';
	num_pieces				= (num_pieces) ? num_pieces : 1;
	fab_width				= (fab_width) ? fab_width : 42;
	if ((height <= fab_width) || height.length) 
	{
		if (height.length && num_pieces.length) 
		{
			for (i=0, n=height.length; i<n; i++) 
			{
				if (inches > height[i]) 
				{
					pieces_per_strip	= Math.floor(inches / height[i]);
					inches				-= ((num_pieces[i] > pieces_per_strip) ? pieces_per_strip : num_pieces[i]) * height[i];
					num_pieces[i]		-= pieces_per_strip;
				}
				if (num_pieces[i] > 0) 
				{
					pieces_per_strip	= Math.floor(fab_width / height[i]);
					num_strips			+= Math.ceil(num_pieces[i] / pieces_per_strip);
					inches				= fab_width - ((num_pieces[i] % pieces_per_strip) * height[i]);
				}
			}
		}
		else 
		{
			pieces_per_strip	= Math.floor(fab_width / height);
			num_strips			= Math.ceil(num_pieces / pieces_per_strip);
		}
	}
	else 
	{
		height	*= num_pieces;
		height	+= (Math.ceil(height / fab_width)) * connect;
		num_strips	= Math.ceil(height / fab_width);
	}
	return num_strips;
}

/* -----------------------------------------------------------------------------
	calc_tri_strips(height[, num_pieces[, type]]);
		height		MIXED		number
		num_pieces	MIXED		integer
		seam
		type
				REQUIRED fab_width
		RETURN (INTEGER) number of strips
----------------------------------------------------------------------------- */
function calc_tri_strips(height, num_pieces, type) 
{
	var num_strips			= 0, 
		num_rect			= 0, 
		width				= 0, 
		pieces_per_strip	= 0;
	num_pieces	= (num_pieces) ? num_pieces : 1;
	type		= (type) ? type : 'hst';
	fab_width				= (fab_width) ? fab_width : 42;
	switch (type) 
	{
		case 'qst':	//	quarter square triangle 5/8 + 5/8 + 1/4 + 1/4
			width				= height + 1.75;
			pieces_per_strip	= Math.floor(fab_width / width);
			pieces_per_strip	+= pieces_per_strip - 1;
			num_strips			= Math.ceil(num_pieces / pieces_per_strip);
			break;
		case 'sga':	//	square goose A
			//	1-1/8 for 2
			num_rect	= Math.ceil(num_pieces / 2);
			width		= height + 1.125;
			num_strips	= calc_strips(width, num_rect);
			break;
		case 'sgb':	//	square goose B
			width				= height + 1.375;
			pieces_per_strip	= Math.floor(fab_width / width);
			pieces_per_strip	+= pieces_per_strip - 1;
			num_strips			= Math.ceil(num_pieces / pieces_per_strip);
			break;
		default:	//	half square triangle 1/4 + 5/8 + 3/8
			num_rect	= Math.ceil(num_pieces / 2);
			width		= height + 1.25;
			num_strips	= calc_strips(width, num_rect);
	}
	return num_strips;
}

/* -----------------------------------------------------------------------------
	parse_args(args);
		args	ARRAY	special argument array
		RETURN (ARRAY) regular argument array
----------------------------------------------------------------------------- */
function parse_args(args) 
{
	var arr = [], 
		i;
	if (args.length > 0) 
	{
		for (i=0; args[i]; i++) 
		{
			arr[i]	= args[i];
		}
	}
	return arr;
}

/* -----------------------------------------------------------------------------
	calc_yds_str(width[, strips]);
		width	NUMBER		strip width OR total width
		strips	INTEGER		number of strips OR empty
				REQUIRED format_fraction(), fab_width
		RETURN (STRING) HTML string of yards OR fat quarters
----------------------------------------------------------------------------- */
function calc_yds_str(width, strips) 
{
	var inches	= (strips > 0) ? width * strips : width, 
		yd, 
		str, 
		num;
	if (fab_width == 20) 
	{
		yd	= 18;
		num	= Math.ceil(inches / yd);
		str	= (num > 1) ? 'fat quarters' : 'fat quarter';
	}
	else 
	{
		yd	= 36;
		num	= inches / yd;
		str	= (num > 1.875) ? 'yds' : 'yd';
		num	= format_fraction(num, 8);
	}
	return num + ' ' + str;
}

/* -----------------------------------------------------------------------------
	set_info(element, info);
		element	STRING		DOM ID string
		info	STRING		information string NOT fabric type
				REQUIRED fab_width
		RETURN (BOOLEAN) success OR failure
----------------------------------------------------------------------------- */
function set_info(element, info) 
{
	if (element && info && fab_width) 
	{
		info	+= ' using ' + ((fab_width == 20) ? 'fat quarters' : (fab_width+2) + ' inch fabric bolt width') + '.';
		if (document.getElementById(element)) 
		{
			document.getElementById(element).innerHTML	= info;
			return true;
		}
		else 
		{
			return false;
		}
	}
	else 
	{
		return false;
	}
}

/* -----------------------------------------------------------------------------
	Fabric(id);
		id		STRING
		RETURN (OBJECT) fabric object constructor
----------------------------------------------------------------------------- */
function Fabric(id) 
{
	//	properties
	this.id			= 'fab' + id;
	this.inches		= 0;
	if (document.getElementById(this.id)) 
	{
		this.element	= document.getElementById(this.id);
	}
	else 
	{
		
	}
	//	methods
}

/* -----------------------------------------------------------------------------
	add_fabrics(obj, fab_id_n);
		obj			ARRAY
		fab_id_n	INTEGER
		RETURN (ARRAY) fabric object array
----------------------------------------------------------------------------- */
function add_fabrics(obj, fab_id_n) 
{
	var n = obj.length, 
		i;
	if (arguments.length > 1) 
	{
		for (i=1; arguments[i]; i++, n++) 
		{
			obj[n]	= new Fabric(arguments[i]);
		}
	}
}

/* -----------------------------------------------------------------------------
	format_subcut_instr(strip_str, piece[, num[, height[, width]]]);
		width	NUMBER	
		strips	INTEGER	
		piece	STRING	
		num		INTEGER	
		height	NUMBER	
		REQUIRED format_fraction()
		RETURN (MIXED) HTML strip/piece subcut instructions OR false on failure
----------------------------------------------------------------------------- */
function format_subcut_instr(strip_str, piece, num, height, width) 
{
	var instr, 
		height_str, 
		width_str, 
		new_piece;
	num			= (num) ? num : 1;
	height_str	= (height) ? format_fraction(height, 8) : '';
	inch_str	= (height > 1) ? 'inches' : 'inch';
	width_str	= (width) ? format_fraction(width, 8) : '';
	piece		+= (num > 1) ? 's' : '';
	instr		= '&nbsp;Subcut ' + strip_str + ' into ' + num + ' ' + piece;
	if (piece.search('rectangle') != -1) 
	{
		instr	+= ' ' + width_str + ' by ' + height_str + ' ' + inch_str + '.';
	}
	else if (piece.search('triangle') != -1) 
	{
		if (piece.search('template') == -1) 
		{
			new_piece	= piece.replace(/<b>\w+<\/b>/,"");
			instr	+= ' using a ' + new_piece.slice(0, -1) + ' ruler.';
		}
		else 
		{
			instr	+= ' (see instructions below).';
		}
	}
	else 
	{
		instr	+= '.';
	}
	return instr;
}


/* -----------------------------------------------------------------------------
	format_cut_instr(width[, strips[, piece[, num[, height]]]]);
		width	NUMBER	
		strips	INTEGER	
		piece	STRING	
		num		INTEGER	
		height	NUMBER	
		REQUIRED format_fraction(), format_subcut_instr()
		RETURN (MIXED) HTML strip/piece cut instructions OR false on failure
----------------------------------------------------------------------------- */
function format_cut_instr(width, strips, piece, num, height) 
{
	var instr, 
		strip_str, 
		width_str, 
		height_str, 
		inch_str;
	if (width) 
	{
		strips		= (strips) ? strips : 1;
		width_str	= format_fraction(width, 8);
		strip_str	= (strips > 1) ? 'strips' : 'strip';
		inch_str	= (width > 1) ? 'inches' : 'inch';
		instr		= '<br />Cut ' + strips + ' ' + strip_str + ' ' + width_str + ' ' + inch_str + ' wide.';
		if (piece) 
		{
			instr	+= format_subcut_instr(strip_str, piece, num, height, width);
		}
		return instr;
	}
	else 
	{
		return false;
	}
}

/* -----------------------------------------------------------------------------
	new_image(src[, title[, class_name]]);
		src			STRING
		title		STRING
		class_name	STRING
		RETURN (OBJECT) HTML DOM image object
----------------------------------------------------------------------------- */
function new_image(src, title, class_name) 
{
	var oimg	= new Image();
	oimg.src	= src;
	if (title) 
	{
		oimg.alt	= title;
		oimg.title	= title;
	}
	if (class_name) 
	{
		oimg.className	= class_name;
	}
	return oimg;
}

/* -----------------------------------------------------------------------------
	Preview(blocks, borders, sashing);
		blocks	ARRAY
		borders	ARRAY
		sashing	ARRAY
		RETURN (OBJECT) Preview object
----------------------------------------------------------------------------- */
function Preview() 
{
	this.block		= '';
	this.sashing	= '';
	this.borders	= '';
}

/* -----------------------------------------------------------------------------
	set_preview(cols, rows, img_obj);
		cols		
		rows		
		img_obj		
		RETURN (OBJECT) DOM table object
----------------------------------------------------------------------------- */
function set_preview(cols, rows, img_obj) 
{
	var block	= 'images/balkan_puzzle_12.jpg', 
		up_left	= 'images/balkan_puzzle_12_up_left.jpg', 
		up_right	= 'images/balkan_puzzle_12_up_right.jpg', 
		lo_left	= 'images/balkan_puzzle_12_lo_left.jpg', 
		lo_right	= 'images/balkan_puzzle_12_lo_right.jpg', 
		top		= 'images/balkan_puzzle_12_top.jpg', 
		left	= 'images/balkan_puzzle_12_left.jpg', 
		right	= 'images/balkan_puzzle_12_right.jpg', 
		bottom	= 'images/balkan_puzzle_12_bottom.jpg', 
		otable	= document.getElementById('mgq_preview'), 
		i, 
		ii, 
		orow, 
		ocell, 
		oimg;
	//	clear table
	for (i=0; otable.rows.length > 0; i++) 
	{
		otable.deleteRow(0);
	}
	//	top
	orow	= otable.insertRow(-1);
	oimg	= new_image(up_left, 'cornerstone', 'corner');
	ocell	= orow.insertCell(-1);
	ocell.appendChild(oimg);
	for (i=0; i<cols; i++) 
	{
		oimg	= new_image(top, 'top border', 'horiz');
		ocell	= orow.insertCell(-1);
		ocell.appendChild(oimg);
	}
	oimg	= new_image(up_right, 'cornerstone', 'corner');
	ocell	= orow.insertCell(-1);
	ocell.appendChild(oimg);
	//	blocks
	for (i=0; i<rows; i++) 
	{
		orow	= otable.insertRow(-1);
		oimg	= new_image(left, 'left border', 'vert');
		ocell	= orow.insertCell(-1);
		ocell.appendChild(oimg);
		for (ii=0; ii<cols; ii++) 
		{
			oimg	= new_image(block, 'block', 'block');
			ocell	= orow.insertCell(-1);
			ocell.appendChild(oimg);
		}
		oimg	= new_image(right, 'right border', 'vert');
		ocell	= orow.insertCell(-1);
		ocell.appendChild(oimg);
	}
	//	bottom
	orow	= otable.insertRow(-1);
	oimg	= new_image(lo_left, 'cornerstone', 'corner');
	ocell	= orow.insertCell(-1);
	ocell.appendChild(oimg);
	for (i=0; i<cols; i++) 
	{
		oimg	= new_image(bottom, 'bottom border', 'horiz');
		ocell	= orow.insertCell(-1);
		ocell.appendChild(oimg);
	}
	oimg	= new_image(lo_right, 'cornerstone', 'corner');
	ocell	= orow.insertCell(-1);
	ocell.appendChild(oimg);
}

/* -----------------------------------------------------------------------------
	[STRING] format_mgq_info(NUMBER num, NUMBER size);
----------------------------------------------------------------------------- */
function format_mgq_info(num, size) 
{
	return num + ' - ' + format_fraction(size, 8) + '" ' + ((num > 1) ? 'blocks' : 'block') + ' using ' + ((fab_width > 22) ? (fab_width + 2) + '" fabric bolt width' : 'fat quarters') + '.'
}

/* -----------------------------------------------------------------------------
	[BOOLEAN] element_inner(STRING element, STRING inner, BOOLEAN append)
----------------------------------------------------------------------------- */
function element_inner(element, inner, append) 
{
	var success	= false;
	element	= (element) ? document.getElementById(element) : false;
	if (element) 
	{
		append	= (append === true) ? true : false;
		if ((append === true) && (element.innerHTML)) 
		{
			element.innerHTML	+= inner;
		}
		else 
		{
			element.innerHTML	= inner;
		}
		return true;
	}
	else 
	{
		return false;
	}
}
