/**
 * ListView()
 *
 * @author   Sean McCann
 * @version  1.0
 * @date     2005.09.15
 *
 * Changelog:
 */

/**
 * Displays formatted set of results for a client quick search
 */
function ListView( )
{
	try
	{
		// Keep this here to copy over properties
		// from the parent prototype object
		create_class_properties.call(this, ListView);

		this.view_element_id = ''; // default id

		// Only uncomment this line if the view_element_id is set
		//this.view_element = document.getElementById(this.view_element_id);

		this.item_view = null;

		this.items = new Array();

		this.item_with_disabled_controls = null;
	}
	catch(e)
	{
		error_message(e, "List.js", 'ListView');
	}
}


ListView.prototype = new View();
ListView.prototype.__CLASS__ = "ListView";
ListView.prototype.createView = ListViewCreateView;
ListView.prototype.setItemView = ListViewSetItemView;
ListView.prototype.addItem = ListViewAddItem;
ListView.prototype.removeItem = ListViewRemoveItem;
ListView.prototype.updateControls = ListViewUpdateControls;
ListView.prototype.getIndexOfItem = ListViewGetIndexOfItem;
ListView.prototype.createItem = ListViewCreateItem;

/**
 * Creates the initial representation of our list
 * @param array models
 */
function ListViewCreateView( models )
{
	try
	{
		var new_view_element;
		var new_item_view;
		var hr;

		new_view_element = document.createElement('div');
		new_view_element.setAttribute('id', this.view_element_id);

		var i = 0;
		var first = true;

		while (i < models.length)
		{
			if (typeof(models[i]) != 'undefined')
			{
				if (!first)
				{
					hr = document.createElement('hr');
					new_view_element.appendChild(hr);
				}
				new_item_view = this.createItem(models[i]);
				new_view_element.appendChild(new_item_view.getElement());

				new_item_view.setIndex(this.items.length);
				this.items[this.items.length] = new_item_view;

				first = false;
			}
			i++;
		}

		// Update the list controls
		this.updateControls();

		return new_view_element;
	}
	catch(e)
	{
		error_message(e, "List.js", 'ListViewCreateView');
		return false;
	}
}


function ListViewCreateItem( model )
{
	try
	{
		var item;

		item = new this.item_view;
		item.setList(this);
		item.setOption('enable_caching', false);
		item.setOption('update_display', false);
		item.display(model);

		return item;
	}
	catch(e)
	{
		error_message(e, "List.js", "ListViewCreateItem");
		return false;
	}

}

/**
 * Specifies which View will be used for each item in the list
 *
 * @param function item_view  a reference to the View class used to display each item
 */
function ListViewSetItemView ( item_view )
{
	try
	{
		var old_item_view;

		old_item_view = this.item_view;
		this.item_view = item_view;

		return old_item_view;
	}
	catch(e)
	{
		error_message(e, "List.js", 'ListViewSetItemView');
		return false;
	}
}


function ListViewAddItem( model, insert_index )
{
	try
	{
		var item;
		var hr;
		var pivot_element;
		var i;


		item = this.createItem(model);

		// Since we will be putting new elements into our
		// display, we need to make sure that it exists beforehand.
		if (!this.view_element)
		{
			var old_options = this.options;
			this.setOption('update_display', false);
			this.display();
			this.options = old_options;
		}

		// If no insertion index was specified, add
		// the new item to the end of our list
		if (typeof(insert_index) == 'undefined')
		{
			insert_index = this.list.length;
		}

		// If this isn't an index that's already in the array, then
		// we will be inserting this at the end of our view.
		if (typeof(this.items[insert_index]) == 'undefined')
		{
			if (this.items.length > 0)
			{
				hr = document.createElement('hr');
				this.view_element.appendChild(hr);
			}
			this.view_element.appendChild(item.getElement());
		}
		// Otherwise, figure out where the new view needs to go
		// and place it in there.
		else
		{
			pivot_element = this.items[insert_index].getElement();
			this.view_element.insertBefore(item.getElement(), pivot_element);

			hr = document.createElement('hr');
			this.view_element.insertBefore(hr, pivot_element);
		}

		// Insert the item
		this.items.splice(insert_index, 0, item);

		// Update indeces of all other items in the list
		for (i = insert_index; i < this.items.length; i++)
		{
			this.items[i].setIndex(i);
		}


		// Update the list controls
		this.updateControls();

		return true;
	}
	catch(e)
	{
		error_message(e, 'List.js', "ListViewAddItem");
		return false;
	}
}

function ListViewRemoveItem( item )
{
	try
	{
		var i = 0;
		var j;
		var item_element;


		i = this.getIndexOfItem(item);
		if (i < 0)
		{
			return false;
		}
		else {
			item_element = this.items[i].getElement();

			// Remove the <hr> separator if one exists
			if (item_element.nextSibling && item_element.nextSibling.nodeName == 'HR')
			{
				this.view_element.removeChild(item_element.nextSibling);
			}
			// In the event that we remove the very last item in the list, remove the separator
			// coming immediately before that item
			else if (item_element.nextSibling === null && item_element.previousSibling && item_element.previousSibling.nodeName == 'HR')
			{
				this.view_element.removeChild(item_element.previousSibling);
			}

			this.view_element.removeChild(item_element);
			this.items.splice(i, 1);

			// Update indeces of all other items in the list
			for (j = i; j < this.items.length; j++)
			{
				this.items[j].setIndex(j);
			}
		}

		// Update the list controls
		this.updateControls();

		return true;
	}
	catch(e)
	{
		error_message(e, 'List.js', "ListViewRemoveItem");
		return false;
	}
}


/**
 * Checks for cases when the controls to add/remove items
 * may need to be enabled or disabled, and does so.
 */
function ListViewUpdateControls ()
{
	try
	{
		// If we are only left with one item, removing it
		// would make the form useless.  So, if that's the
		// case, then disable the control that lets the user
		// remove that item from the list.
		if (this.items.length == 1)
		{
			this.items[0].disableRemoveControl();
			this.item_with_disabled_controls = this.items[0];
		}

		// Otherwise, make sure that the removal control works
		else if (this.item_with_disabled_controls)
		{
			this.item_with_disabled_controls.enableRemoveControl();
			this.item_with_disabled_controls = null;
		}

		return true;
	}
	catch (e)
	{
		error_message(e, 'List.js', "ListViewUpdateControls");
		return false;
	}
}

/**
 * @param ListItemView item   the view that we wish to obtain the index of
 * @return int
 */
function ListViewGetIndexOfItem( item )
{
	try
	{
		return array_search(item, this.items);
	}
	catch(e)
	{
		error_message(e, 'List.js', "ListViewGetIndexOfItem");
		return -1;
	}
}