// Orangeview Inventory System
// (c) 2007 Christer Kaitila

// fixme: you cant drop or put away a carried quest item - bug on drop:0 items
// fixme: it would be nice to be able to force pickup at a certain slot (reorder)
// fixme: each new inv() clears then regenerates inv gui html (flicker) but ok not polled

var inventoryversion = "v2.00"; // recycle bin hacked in, addlog not alert.. if (num==-666) // trashcan

var pickups_change_mouse_cursor = false; // more subtle
var inventory_needs_loading = true; // loaded upon first display using ajax
var inventory_url = 'inventory.php?'; // the ajax url
var inventory_cache_url = 'cacheinventory.php?f='; // cached images
var blank_gif_url = 'cache.php?f=blank.gif'; // default image
var world_element = null; // document.body; // fixme ie6 no body? lowlevel
var carrying_element = null; // pointer to an html ele that we are dragging
var hovering_the_inventory = false; // where to drop carried item
var pickup_clone_parent_id = 'pickups'; // base element that is a pickup
var pickup_spawn_offset = -32; // so it is centered where you clicked
var inventory_slots = 9; //8 number of allowable slots
var inventory_hover_height = '-64px';
var inventory_xbutton_height = '-32px'; // inv x button
var inventory_xbutton_height_when_big = '-64px';
var inventory_button_height = '-32px'; // unused buttons
var inv_is_big = false; // toggle
var inv_small_height_css = '76px'; // must match css #inventory, #inv_bg
var inv_big_height_css = '396px'; // 448 minus empty space

//var inv_shrink_bottom_position = '-292px'; // must match css
//var inv_grow_bottom_position = '32px';
//var inv_right_position = '40px'; // must match css


var itemdata =		// all known item types
{
	//axe: 			{ name:'rusty axe', desc:'A salvaged hand axe, this rusty tool is invaluable for survival.  Use on a palm tree to produce wood.', qmax:1, mass:10, drop:1, give:0, cost:0, img:'axe.gif' } ,
	//plank:		{ name:'wood plank', desc:'Planks that have been made from a chopped-down palm tree.  Use in your village to build.', qmax:10, mass:5, drop:1, give:1, cost:2, img:'plank.gif' } ,
	//shovel:		{ name:'sturdy shovel', desc:'A sturdy shovel, ideal for digging in loose sand and soil.  Use on the beach to find oysters.', qmax:5, mass:15, drop:1, give:1, cost:20, img:'shovel.gif' } ,
	//oyster:		{ name:'fresh oyster', desc:'The perfect food, plentiful and full of protein.  Oysters occasionally contain a pearl.', qmax:20, mass:1, drop:1, give:1, cost:2, img:'oyster.gif' } ,
	//pearl:		{ name:'natural pearl', desc:'Shiny, round, smooth and valuable, pearls glimmer all shades of the rainbow, and feel warm to the touch.', qmax:999999999, mass:0, drop:1, give:1, cost:15, img:'pearl.gif' } ,

	gemsquare:	{ name:'square-cut gem', desc:'Exquisitely cut gemstone that sparkles with light.', qmax:999999999, mass:0, drop:1, give:1, cost:1250, img:'gemsquare.gif' } ,
	gemtear:	{ name:'tear-cut gem', desc:'Exquisitely cut gemstone that sparkles with light.', qmax:999999999, mass:0, drop:1, give:1, cost:525, img:'gemtear.gif' } ,
	gemcircle:	{ name:'circle-cut gem', desc:'Exquisitely cut gemstone that sparkles with light.', qmax:999999999, mass:0, drop:1, give:1, cost:720, img:'gemcircle.gif' },
	coin:		{ name:'gold coin', desc:'Heavy gold coins that hold within them the promise of vast wealth.', qmax:999999999, mass:0,drop:1, give:1, cost:1, img:'coin.gif' } ,

	chocolates:	{ name:'box of chocolates', desc:'A delicious box of gourmet chocolates.', qmax:1, mass:2, drop:1, give:0, cost:20, img:'chocolates.gif' },
	chocolate0:	{ name:'cherry-filled chocolate', desc:'A chocolate that is filled with cherry.', qmax:999999999, mass:0, drop:1, give:1, cost:1, img:'chocolate0.gif' },
	chocolate1:	{ name:'peanut-filled chocolate', desc:'A chocolate that is filled with peanut butter', qmax:999999999, mass:0, drop:1, give:1, cost:1, img:'chocolate1.gif' },
	chocolate2:	{ name:'dark chocolate', desc:'A star-shaped candy that is made from dark chocolate.', qmax:999999999, mass:0, drop:1, give:1, cost:1, img:'chocolate2.gif' },
	chocolate3:	{ name:'caramel-filled chocolate', desc:'A chocolate that is filled with caramel.', qmax:999999999, mass:0, drop:1, give:1, cost:1, img:'chocolate3.gif' },
	flowers:	{ name:'bouquet of flowers', desc:'A fresh bouquet of flowers that smells wonderful.', qmax:1, mass:2, drop:1, give:0, cost:20, img:'flowers.gif' },
	flower0:	{ name:'rose', desc:'A delicate, long-stemmed rose that smells fresh.', qmax:999999999, mass:0, drop:1, give:1, cost:1, img:'flower0.gif' } ,

	apple:		{ name:'shiny apple', desc:'Delicious and healthy apple.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Apple.gif' },
	banana:		{ name:'ripe banana', desc:'Ripe yellow banana.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Banana.gif' },
	book:		{ name:'interesting book', desc:'Popular non-fiction book.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Book.gif' },
	brocoli:	{ name:'steamed brocoli', desc:'Freshly cooked brocoli, best served with cheese.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Brocoli.gif' },
	bucket:		{ name:'wooden bucket', desc:'Sturdy water bucket.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Bucket.gif' },
	cherry:		{ name:'tasty cherry', desc:'Freshly picked cherry.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Cherry.gif' },
	coffee:		{ name:'coffee', desc:'Hot coffee that smells great.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Coffee.gif' },
	cookie:		{ name:'chocolate-chip cookie', desc:'Crunchy cookie that is still warm and chewy in the middle.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Cookie.gif' },
	corn:		{ name:'fresh corn', desc:'Bright yellow cob of corn.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Corn.gif' },
	cupcake:	{ name:'sweet cupcake', desc:'Freshly backed cupcake with icing.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Cupcake.gif' },
	dessert:	{ name:'ice-cream dessert', desc:'Delicious treat.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Dessert.gif' },
	glove:		{ name:'boxing glove', desc:'Bright red boxing glove.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Glove.gif' },
	lemon:		{ name:'sliced lemon', desc:'Zesty yellow lemon.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Lemon.gif' },
	lily:		{ name:'white lily', desc:'Fresh Easter Lily that smells wonderful.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Lily.gif' },
	loaf:		{ name:'bread loaf', desc:'Loaf of bread that just came from the oven.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Loaf.gif' },
	mushroom:	{ name:'wild mushroom', desc:'Wild mushrooms from the forest.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Mushroom.gif' },
	newspaper:	{ name:'newspaper', desc:'The Kool Community Times.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Newspaper.gif' },
	novel:		{ name:'bestselling novel', desc:'A popular story about two friends.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Novel.gif' },
	onion:		{ name:'onion', desc:'Perfect for cooking.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Onion.gif' },
	orange:		{ name:'orange', desc:'Delicious fresh juicy orange.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Orange.gif' },
	pea:		{ name:'sweet pea', desc:'Crunchy green peas.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Pea.gif' },
	pepper:		{ name:'green pepper', desc:'Crunchy green pepper.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Pepper.gif' },
	pie:		{ name:'cherry pie', desc:'Freshly baked home-made cherry pie.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Pie.gif' },
	pizza:		{ name:'pepperoni pizza', desc:'Gooey baked pizza slice.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Pizza.gif' },
	popcorn:	{ name:'popcorn', desc:'Movie popcorn with buttery topping.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Popcorn.gif' },
	soap:		{ name:'soap bar', desc:'Bar of soap.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Soap.gif' },
	soda:		{ name:'soda can', desc:'Ice-cold can of soda pop.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Soda.gif' },
	strawberry:	{ name:'strawberry', desc:'Fresh juicy strawberries.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Strawberry.gif' },
	teapot:		{ name:'teapot', desc:'Hot teapot.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Teapot.gif' },
	tissue:		{ name:'tissue', desc:'Box of facial tissues.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Tissue.gif' },
	trumpet:	{ name:'trumpet', desc:'Shiny toy trumpet.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Trumpet.gif' },
	violin:		{ name:'violin', desc:'Exquisitly crafted wooden violin.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Violin.gif' },
	wagon:		{ name:'sturdy wagon', desc:'Well built red wagon.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Wagon.gif' },
	watermelon:	{ name:'juicy watermelon', desc:'Very juicy pink watermelon.', qmax:99, mass:1, drop:1, give:1, cost:1, img:'Watermelon.gif' }
};

function inventory_class()
{	// object constructor
	this.items = Array();	// associative array of 'name':'quantity'
	this.slots = Array();	// nine spaces on the gui
	this.slotcount = 0;	// how many in use
	this.slotmax = inventory_slots;	// how many total
	// function pointers
	this.fromstring = inventory_fromstring;
	this.tostring = inventory_tostring;
	this.num = inventory_num;
	this.empty = inventory_empty;
	this.total_weight = inventory_total_weight;
	this.pickup = inventory_pickup;
	this.drop = inventory_drop;
	this.listitems = inventory_listitems;
	this.listdata = inventory_listdata;
	this.describe_html = inventory_describe_html;
	this.findfreeslot = inventory_findfreeslot;
	this.which_slot = inventory_which_slot;
	this.which_item = inventory_which_item;
}


function lowlevel_getelementbyid(thisid)
{
	return document.getElementById(thisid);
}

function inventory_gui_show()
{
	var gotit = lowlevel_getelementbyid('inv_bg');
	if (gotit) gotit.style.display='block';
	gotit = lowlevel_getelementbyid('inventory');
	if (gotit) gotit.style.display='block';
}

function inventory_gui_hide()
{
	var gotit = lowlevel_getelementbyid('inv_bg');
	if (gotit) gotit.style.display='none';
	gotit = lowlevel_getelementbyid('inventory');
	if (gotit) gotit.style.display='none';
}

function inventory_gui_grow()
{
	if (inventory_needs_loading)
	{
		download_inventory();
		inventory_needs_loading = false;
	}

	inv_is_big = true;

	var gotit = lowlevel_getelementbyid('inv_bg');
	if (gotit)
	{
		gotit.style.height = inv_big_height_css;
		//gotit.style.bottom = inv_grow_bottom_position;
		//gotit.style.right = inv_right_position;
	}
	gotit = lowlevel_getelementbyid('inventory');
	if (gotit)
	{
		gotit.style.height = inv_big_height_css;
		//gotit.style.bottom = inv_grow_bottom_position;
		//gotit.style.right = inv_right_position;
	}
}

function inventory_gui_shrink()
{
	inv_is_big = false;

	var gotit = lowlevel_getelementbyid('inv_bg');
	if (gotit)
	{
		gotit.style.height = inv_small_height_css;
		//gotit.style.bottom = inv_shrink_bottom_position;
		//gotit.style.right = inv_right_position;
	}
	gotit = lowlevel_getelementbyid('inventory');
	if (gotit)
	{
		gotit.style.height = inv_small_height_css;
		//gotit.style.bottom = inv_shrink_bottom_position;
		//gotit.style.right = inv_right_position;
	}
}

function inventory_fromstring(astring,emptyfirst) // eg "50_coin,1_axe"
{
	//addlog('DEBUG: inventory fromstring:\n' + astring);
	if (!astring) return;
	if (astring.length<3) return;
	if (emptyfirst)
	{	// empty old data - fixme: drop so that gui images go away!
		this.empty();
	}
	var slotdata = null;
	var slotquantity = 0;
	var slotname = '';
	var someslots = astring.split(',');
	for (oneslot in someslots)
	{
		//addlog('DEBUG parsing ' + someslots[oneslot]);
		slotdata = someslots[oneslot].split('_');
		slotquantity = parseInt(slotdata[0]);
		if ((slotquantity>0) && (slotdata[1]))
		{
			this.pickup(slotdata[1],slotquantity,true); // true = do not submit
		}
	}
}

function inventory_tostring() // eg "50_coin,1_axe"
{
	var thestring = '';
	for (eachone in this.items)
	{
		if (this.items[eachone] > 0) // quantity
		{
			if (thestring.length) thestring += ',';
			thestring += this.items[eachone] + '_' + eachone;
		}
	}
	//addlog('DEBUG: inventory tostring = '+thestring);
	return thestring;
}

function inventory_num(itemname) // eg num('gold');
{
	if (this.items[itemname])
		return this.items[itemname];
	else
		return 0;
}

function inventory_empty()
{
	this.items = Array();
	this.slots = Array();
	clear_inventory_gui();
}

function inventory_total_weight() // adds up all items x mass
{
	var tot = 0;
	for (eachone in this.items)
	{
		if ((this.items[eachone]) && (itemdata[eachone]))
		{
			tot += itemdata[eachone].mass * this.items[eachone];
		}
	}
	return tot;
}

function inventory_pickup(itemname,qqq,donotsubmit) // eg pickup('pearl',5);
{	// returns true if picked at least one up
	if (!qqq) qqq=1; // default pickup one - zero, null etc all mean 1
	if (window.xhair_change_frame) xhair_change_frame(0); // xhair reset
	if (!itemdata[itemname])
	{
		change_inventory_description('Unknown item type ' + itemname);
		return false; //-1;
	}
	change_inventory_description('You pick up '+qqq+' <b>'+itemdata[itemname].name + invplural(qqq) + '</b>.');
	var oldquantity = 0;
	if (this.items[itemname])
	{	// already have some
		oldquantity = this.items[itemname];
		this.items[itemname] += qqq;
	}
	else
	{
		var newslot = this.findfreeslot();
		if (newslot != -1)
		{
			this.slots[newslot] = itemname;
			// load img
			theimg = lowlevel_getelementbyid('iii'+newslot);
			if ((theimg) && (itemdata[itemname]))
			{
				theimg.src = inventory_cache_url+itemdata[itemname].img;
			}
			this.items[itemname] = qqq;
		}
		else
		{
			change_inventory_description('You cannot pick up any more items - no free slots.');
			return false; //-1;
		}
	}
	if (itemdata[itemname])
	{
		if (this.items[itemname]>itemdata[itemname].qmax)
		{	// maxed out? only take SOME of them.  fixme: drop a smaller quantity back on the floor?
			this.items[itemname]=itemdata[itemname].qmax;
			change_inventory_description('You can carry a maximum of ' + itemdata[itemname].qmax + ' ' + itemdata[itemname].name + invplural(this.items[itemname]) + '.');
		}
	}

	if (oldquantity==this.items[itemname])
	{
		return false; // don't pick up
	}
	else
	{

		// change quantity text (eg x10)
		var oldslot = this.which_slot(itemname);
		theqqq = lowlevel_getelementbyid('iq'+oldslot);
		if (theqqq) theqqq.innerHTML = ((this.items[itemname]<2) ? '' : ('x'+this.items[itemname]));

		if (!donotsubmit)
			submit_inventory(); // tell server about the new change!

		return true; // picked 'it' or 'some' up
	}
}

function inventory_drop(itemname,qqq) // eg drop('pearl');
{	// fixme: return true/false like pickup
	if (qqq==null) qqq=1;

	if (!itemdata[itemname])
	{
		change_inventory_description('Unknown item type ' + itemname);
		return -1;
	}

	if (!itemdata[itemname].drop)
	{
		change_inventory_description('The '+ itemname + ' is un-droppable because it is a quest item.');
		return -1;
	}

	if (this.items[itemname])
	{
		if (qqq<this.items[itemname])
		{
			change_inventory_description('You dropped '+qqq+' '+itemdata[itemname].name+invplural(qqq)+'.');
			this.items[itemname] -= qqq;
		}
		else
		{
			//addlog('DEBUG: drop maxed out: qqq('+qqq+')<=this.items[itemname]('+this.items[itemname]);
			qqq = this.items[itemname]; // bottom out at 0
			change_inventory_description('You dropped '+qqq+' '+itemdata[itemname].name+invplural(qqq)+'.  You do not have any more '+itemdata[itemname].name+'s.');
			this.items[itemname] = 0;
		}


	}
	else
	{
		change_inventory_description('You do not have any more '+itemdata[itemname].name+'s.');
		return -1;
	}

	var oldslot = this.which_slot(itemname);
	if (oldslot != -1)
	{
		// change quantity text
		theqqq = lowlevel_getelementbyid('iq'+oldslot);
		if (theqqq) theqqq.innerHTML = ((this.items[itemname]<2) ? '' : ('x'+this.items[itemname]));

		if (this.items[itemname]==0) // none left?
		{
			//this.items.splice(itemname,1); // fixme
			// empty img
			theimg = lowlevel_getelementbyid('iii'+oldslot);
			if ((theimg) && (itemdata[itemname]))
			{
				theimg.src = blank_gif_url;
			}

			this.slots[oldslot] = null;
			//this.slots.splice(newslot,1); // fixme
		}
	}

	submit_inventory(); // tell server about the new change!
	return this.items[itemname];
}

function inventory_listitems()
{
	var str = '';
	for (eachone in this.items)
	{
		if (str.length>0) str += ", ";
		str += eachone;
	}
	return str;
}

function inventory_listdata() // debug only
{
	var str = '';
	for (eachone in this.items)
	{
		if (str.length>0) str += "<br>";
		str += this.items[eachone] + ' ' + eachone + invplural(this.items[eachone]);
		if (itemdata[eachone])
		{
			str += this.describe_html(eachone) + '<br> - TOTAL MASS: ' + itemdata[eachone].mass * this.items[eachone] + ' kg' + '<br> - TOTAL VALUE: ' + itemdata[eachone].cost * this.items[eachone] + ' gold';
		}
	}
	return '<b>Inventory:</b><br>' + str;
}

function inventory_describe_html(itemname)
{
	var str = '';
	if (itemdata[itemname])
	{
		var thecount = 0;
		if (this.items[itemname]) thecount = this.items[itemname];
		str += '<b>' + thecount + ' ' + itemdata[itemname].name + invplural(thecount) + '</b><br><br>Description: ' + itemdata[itemname].desc;
		// + '<br>' + 'Maximum quantity: ' + itemdata[itemname].qmax + '.  ' + 'Mass: ' + itemdata[itemname].mass + ' kg' + '.  ' + 'Value: ' + itemdata[itemname].cost + ' gold' + '.'; //  ' + 'Droppable: ' + (itemdata[itemname].drop ? 'yes' : 'no') + '.  ' + 'Givable: ' + (itemdata[itemname].give ? 'yes' : 'no') + '.  ';
	}
	return str;
}

function inventory_findfreeslot()
{
	for (slotnum=0; slotnum<this.slotmax; slotnum++)
	{
		if (!this.slots[slotnum]) return slotnum;
	}
	return -1;
}

function inventory_which_slot(itemname)
{
	for (var slotnum=0; slotnum<this.slotmax; slotnum++)
	{
		if (this.slots[slotnum]==itemname) return slotnum;
	}
	return -1;
}

function inventory_which_item(slotnum)
{
	if (this.slots[slotnum])
		return this.slots[slotnum];
	else
		return null;
}

function inv_click(num,elem)
{
	if (window.game_sfxclick) game_sfxclick();
	var finalresult = '';
	
	if (num==-666) // trashcan poo
	{
		if (inventory.carrying)
		{
			var feedback = 'You recycle the ';
			if (itemdata[inventory.carrying])
				feedback += itemdata[inventory.carrying].name + '.';
			else
				feedback += 'item.';
			addlog(feedback);
			finalresult += feedback;
			clickeditem = null;
			drop_carrying_element(); // dont put on ground
			//inventory.carrying = null;
			//return;
		}
	}
	
	if (num>-1) // a real slot
	{
		var clickeditem = inventory.which_item(num); // copy text
		//addlog('DEBUG: inv_click slot ' + num + '\nis item ' + inventory.which_item(num) + '\ncarrying ' + inventory.carrying);
		if (inventory.carrying)
		{	// put back in pack
			//addlog('carrying something put back in pack');

			var pickupresult = inventory.pickup(inventory.carrying); // ajax in here if you actually take it

			finalresult += 'You put the '+itemdata[inventory.carrying].name+' back in your inventory.&nbsp; ';

			if (!pickupresult) finalresult += 'But there was no room for it!';

			// same type of item? don't re-pick it up!
			if (clickeditem==inventory.carrying) clickeditem = null;
			// put away
			drop_carrying_element(); // dont put on ground
			inventory.carrying = null;
			return; // dont pickup
		}

		if (itemdata[clickeditem]) // && itemdata[clickeditem].drop) // quest items stay in inventory forever.. dont allow carry?
		{
			inventory.carrying = clickeditem;
			if (inventory.carrying) // slot wasn't empty
			{
				inventory.drop(inventory.carrying); // remove from pack
				finalresult += 'You are now carrying one '+itemdata[inventory.carrying].name+'.&nbsp; Click an inventory slot to put it away, or click the ground to drop it.';
				pickup_and_carry(inventory.carrying);

			}
			else
			{
				finalresult += 'You are now carrying nothing.&nbsp; ';
			}
		}
	}

	if (num==-2) // use
	{
		//addlog('use: ' + inventory.carrying);
		if (inventory.carrying)
		{
			finalresult += 'Using '+inventory.carrying+'.&nbsp; ';
		}
		else
		{
			finalresult += 'You are not holding anything.&nbsp;  Click the item you want to use first.&nbsp; ';
		}
	}

	if (num==-3) // trade
	{
		//addlog('trade: ' + inventory.carrying);
		if (inventory.carrying)
		{
			finalresult += 'Trading '+inventory.carrying+'.&nbsp; Click another user to offer it.&nbsp; ';
		}
		else
		{
			finalresult += 'You are not holding anything.&nbsp; Click the item you want to trade first.&nbsp; ';
		}
	}

	if (num==-1) // trade
	{
		//addlog('inv: toggle X clicked');
		if (inv_is_big)
		{
			inventory_gui_shrink();
		}
		else
		{
			inventory_gui_grow();
		}
	}


	if (finalresult != '') change_inventory_description(finalresult);
}

var inv_desc_ele = null;
function change_inventory_description(thisstr)
{
	if (!inv_desc_ele) inv_desc_ele = lowlevel_getelementbyid('inventory_desc');
	inv_desc_ele.innerHTML = thisstr;
}

function inv_hover(num,elem)
{
	if (window.game_sfxhover) game_sfxhover();
	//addlog('DEBUG: inv_hover ' + num);
	if (num==-1)
		change_inventory_description('Click this button to close the inventory window.');
	else if (num==-2)
		change_inventory_description('Click this button to GIVE the item to somebody.');
	else if (num==-3)
		change_inventory_description('Click this button to DROP the item on the ground.');
	else if (num==-666)
	{
		if (inventory.carrying && itemdata[inventory.carrying])
		{
			change_inventory_description('Click here to discard<br>the <b>'+itemdata[inventory.carrying].name+'</b>.<br>It will be removed from<br>your inventory and recycled.');
		}
		else
		{
			change_inventory_description('Items put here are deleted.');
		}
	}
	else // normal inventory item slot:
	{
		if (inventory.carrying)
		{
			change_inventory_description('Click any slot to put the <b>'+itemdata[inventory.carrying].name+'</b> back into your inventory.&nbsp; ');
		}
		else // not carrying anything: hover displays item info
		{
			var hovereditem = inventory.which_item(num);
			if (hovereditem)
				change_inventory_description(inventory.describe_html(hovereditem));
		}
	}

	hovering_the_inventory = true;

	if ((elem) && (elem.style))
	{	// highlight
		if (num==-1) // x button
		{
			if (inv_is_big)
			{
				elem.style.top= inventory_xbutton_height_when_big;
			}
			else
			{
				elem.style.top=inventory_xbutton_height;
			}
		}
		else if (num==-2) // big buttons at bottom
			elem.style.top=inventory_button_height;
		else if (num==-3) // big buttons at bottom
			elem.style.top=inventory_button_height;
		else // normal slots
			elem.style.top=inventory_hover_height;
	}
}

function inv_out(num,elem)
{
	//addlog('DEBUG: inv_out ' + num);
	//cls:
	//lowlevel_getelementbyid('inventory_desc').innerHTML = '';

	if (num==-666) change_inventory_description('');

	if (inventory.carrying)
	{
		if (itemdata[inventory.carrying])
			change_inventory_description('You are carrying a <b>'+itemdata[inventory.carrying].name+'</b>.<br>Click the ground to drop it, or click<br>an inventory slot to put it away.');
		else
			change_inventory_description('You are carrying am item.<br>Click the ground to drop it, or click<br>an inventory slot to put it away.');
	}

	hovering_the_inventory = false;

	if ((elem) && (elem.style))
	{	// unhighlight
		elem.style.top='0px';
	}
}

function invbasename(thisfilename) // 'path/blank.gif' outputs 'blank'
{
	if (!thisfilename) return '';

	farrpath = thisfilename.split('/');
	if (farrpath[farrpath.length-1])
		thisfilename = farrpath[farrpath.length-1];

	farrpath = thisfilename.split('\\');
	if (farrpath[farrpath.length-1])
		thisfilename = farrpath[farrpath.length-1];

	farrpath = thisfilename.split('='); // for the cache urls eg .php?f=thisfile.gif
	if (farrpath[farrpath.length-1])
		thisfilename = farrpath[farrpath.length-1];

	thisfilename = thisfilename.toLowerCase();

	farr = thisfilename.split('.');
	if (farr[0])
	{
		return farr[0];
	}
	else
		return thisfilename;
}

function pickupover(thiselement)
{
	if (window.game_sfxhover) game_sfxhover();

	if (pickups_change_mouse_cursor)
	{
		if (window.xhair) xhair_change_frame(2); // hand
	}

	if (!inventory.carrying)
	{
		// grab sub element: img
		thisimgs = thiselement.getElementsByTagName('img');
		if (thisimgs && thisimgs[0]) thisimg = thisimgs[0];
		// grab item type via image filename
		if (!thisimg) return;
		if (!thisimg.src) return;
		var hovereditem = invbasename(thisimg.src);
		if (itemdata[hovereditem])
			change_inventory_description('Click to pick up a <b>'+itemdata[hovereditem].name+'</b>.');
		else
			addlog('ERROR: pickupover does not know ' + hovereditem);
	}
}

function pickupout(thiselement)
{
	if (pickups_change_mouse_cursor)
	{
		if (window.xhair)
		{
			if (window.carrying_element)
				xhair_change_frame(2); // hand
			else
				xhair_change_frame(0); // null
		}
	}
	
	if (!inventory.carrying)
	{
		change_inventory_description('');
	}
}

function pickupclick(thiselement)
{
	if (inventory_needs_loading) return; // wait for inventory first

	if (!thiselement) return;
	// sound
	if (window.game_sfxlogin) game_sfxlogin();
	// grab sub element: img
	thisimgs = thiselement.getElementsByTagName('img');
	if (thisimgs && thisimgs[0]) thisimg = thisimgs[0];
	// grab item type via image filename
	if (!thisimg) return;
	if (!thisimg.src) return;
	var grabbed_it = inventory.pickup(invbasename(thisimg.src));
	// make item go away
	if (grabbed_it)
	{	//thiselement.style.display='none';
		world_element.removeChild(thiselement);
		// show the inventory gui if it is hidden
		inventory_gui_show(); // vis
		inventory_gui_grow(); // big
	}
	else
	{
		//addlog('You cannot pick up any more items.'); // full or waiting...
	}
}

function spawnpickup(thisname,thisx,thisy)
{
	if (!thisname) return;
	if (!itemdata[thisname])
	{
		change_inventory_description('Unable to spawn an unknown type of pickup.');
		return;
	}
	newone = invcloneme(pickup_clone_parent_id,thisx+pickup_spawn_offset,thisy+pickup_spawn_offset);
	newone.title = /*itemdata[thisname].name + ' - ' +*/ itemdata[thisname].desc;
	thisimgs = newone.getElementsByTagName('img'); // lowlevel fixme
	if (thisimgs && thisimgs[0]) thisimg = thisimgs[0];
	if (thisimg)
	{
		thisimg.src = inventory_cache_url+itemdata[thisname].img; //+thisname+pickup_file_extension;
		if (debug>1) addlog('DEBUG: the new pickup uses this img: ' + thisimg.src);
	}
	else
	{
		addlog('ERROR: unable to find the img in a pickup.');
	}


}

function pickup_and_carry(thisname)
{
	if (!itemdata[thisname])
	{
		change_inventory_description('Unable to pickup and carry an unknown type of item.');
		return;
	}
	if (debug>1) addlog('DEBUG: pickup_and_carry '+thisname);
	if (carrying_element)
	{
		if (debug) addlog('ERROR: Already carrying something.');
		change_inventory_description('You cannot pick up the '+itemdata[thisname].name+' because you are already holding a '+itemdata[inventory.carrying].name+'.  Click the ground or your inventory to put it away first.');
		return;
	}
	
	carrying_element = lowlevel_getelementbyid('carryingitem');
	if (carrying_element)
	{
		//carrying_element.src = blank_gif_url; // dont show prev during dl
		carrying_element.src = inventory_cache_url+itemdata[thisname].img; //+thisname+pickup_file_extension;
		carrying_element.style.display = 'block';
		// move to last known xhair location
		if (window.xhair)
		{
			carrying_element.style.left = xhair_x+carrying_drag_offset+'px';
			carrying_element.style.top = xhair_y+carrying_drag_offset+'px';
			xhair_change_frame(2); // hand
		}
	}
	else
	{
		addlog('ERROR: carrying_element not found.');
	}
}

function drop_carrying_element(groundx,groundy)
{
	if (debug>1) addlog('DEBUG: drop_carrying_element '+inventory.carrying);
	if (!carrying_element) return;
	if (!inventory.carrying) return;
	if (!itemdata[inventory.carrying].drop)
	{
		change_inventory_description('You cannot drop the '+itemdata[inventory.carrying].name+' on the ground because it is a quest item.');
		return;
	}
	carrying_element.src = blank_gif_url; // dont show prev during dl
	carrying_element.style.display = 'none';
	carrying_element = null; // stop dragging
	if (window.xhair_change_frame) xhair_change_frame(0); // xhair
	if (!hovering_the_inventory)
	{
		if (groundx!=null)
		{
			if (debug>1) addlog('DEBUG: dropping on the ground at '+groundx+','+groundy);
			spawnpickup(inventory.carrying,groundx,groundy);
			change_inventory_description('You dropped a '+itemdata[inventory.carrying].name+' on the ground at ['+groundx+','+groundy+'].');
			inventory.carrying = null;
		}
	}
	//else
	//{	// gets put back into inventory on inv_click
	//	// if (debug) addlog('Dropping on the ground ignored: inv_click will handle it.');
	//}
}

function invcloneme(thisid,xx,yy)
{
	var foundit = lowlevel_getelementbyid(thisid);
	var theclone = null;
	if (foundit)
	{
		xx=parseInt(xx);
		yy=parseInt(yy);
		theclone = foundit.cloneNode(true);
		world_element.appendChild(theclone);
		theclone.style.left=xx+'px';
		theclone.style.top=yy+'px';
		theclone.style.zIndex=yy;
		theclone.style.display='block';
	}
	else
	{
		addlog('ERROR - invcloneme('+thisid+','+xx+','+yy+' could not find parent item.');
	}
	return theclone;
}

function invplural(num) // duped plural function
{
	if (num==1) return ''; else return 's';
}

function spawn_lots_of_items() // debug
{
	for (var loopa=0; loopa<1; loopa++)
	{
		for (nextitem in itemdata)
		{	// spawn one of each known item type
			spawnpickup(nextitem,parseInt(Math.random()*800)+200,parseInt(Math.random()*500));
		}
	}
}

/*
function define_a_zoink() // debug
{
	itemdata.zoink = { name:'zoink', desc:'This class of object was just created on the fly!', qmax:999, mass:10, drop:1, give:1, cost:500, img:'pearl.gif' };
	itemdata.zoinka = itemdata.zoink;
	itemdata.zoinkb = itemdata.zoink;
	itemdata.zoinkc = itemdata.zoink;
	itemdata.zoinkd = itemdata.zoink;
	itemdata.zoinke = itemdata.zoink;
	itemdata.zoinkf = itemdata.zoink;
}

function test_it_a_little() // debug
{
	alert("inventory.num('sand')="+inventory.num('sand')+
	      "\ninventory.num('axe')="+inventory.num('axe')+
	      "\ninventory.num('plank')="+inventory.num('plank'));

	alert("inventory.listitems()="+inventory.listitems()+
	      "\ninventory.total_weight()="+inventory.total_weight());

	alert("inventory.pickup('coin',250)="+inventory.pickup('coin',250)+
	      "\ninventory.pickup('plank',999)="+inventory.pickup('plank',999)+
	      "\ninventory.drop('coin',249)="+inventory.drop('coin',249));

	alert("inventory.listdata()="+inventory.listdata()+
	      "\ninventory.total_weight()="+inventory.total_weight()+' kg');
}
*/

function clear_inventory_gui()
{
	for (slotnum=0; slotnum<inventory_slots; slotnum++)
	{
		// change quantity text
		theqqq = lowlevel_getelementbyid('iq'+slotnum);
		if (theqqq) theqqq.innerHTML = '';
		// empty img
		theimg = lowlevel_getelementbyid('iii'+slotnum);
		if (theimg) theimg.src = blank_gif_url;
	}
}

function inv(amsg) // server inventory update ajax message
{
	if (debug>1) addlog('inventory server response:\n['+amsg+']'); // very common for server to say "blank"
	if (!amsg) return;
	if (!amsg.length) return;
	// parse new data
	inventory.fromstring(amsg,true); // true=empty first
}

function download_inventory() // ask the server
{
	if ((window.ajax) && (window.global_user_name) && (window.global_user_name))
	{
		invvars = 'n='+global_user_name;
		if (debug>1) addlog('DEBUG: downloading inv:' + inventory_url + invvars);
		pendinginvrequest = new ajax(invvars,inventory_url);
	}
	else
	{
		if (debug) addlog('ERROR: download_inventory cannot find ajax or user name.');
	}
}

function submit_inventory() // tell the server
{
	if (inventory_needs_loading)
	{
		addlog('ERROR: inventory_needs_loading so you cannot submit_inventory.');
	}

	if ((window.ajax) && (window.global_user_name))
	{

		invvars = 'n='+global_user_name+'&v='+inventory.tostring();
		if (debug) addlog('DEBUG: submit inventory:' + inventory_url + invvars);
		pendinginvrequest = new ajax(invvars,inventory_url);
	}
	else
	{
		addlog('ERROR: unable to find ajax or user name in submit_inventory.');
	}
}

//addlog('compiled inv...');
world_element = lowlevel_getelementbyid('level');
if (!world_element) addlog('ERROR: Inventory could not find the level element.');
var inventory = new inventory_class();
//addlog('finished inv...');
// works:
// setTimeout("inv('69_coin,7_plank,1_oyster');",5555);
