// $Id: PagingLib.js,v 1.2 2009-11-20 11:59:16 jbesson Exp $

function PagingLib(name, props) {

	// check all the mandatory properties were given
	var i;
	var mandProps = [
		'divId',
		'pageLen'
	];
	for (i = 0; i < mandProps.length; i++) {
		if (typeof props[mandProps[i]] == 'undefined') {
			alert(name + " is broken for PagingLib: " + mandProps[i] + " is not defined");
			non_existant_function();
		}
	}

	// public vars in a container object
	var __pub = {
		pageStart : 0,
		pageEnd   : 0
	};

	// public vars that have defaults but can be overidden
	var overPubProps = [];
	for (i = 0; i < overPubProps.length; i++) {
		if (typeof props[overPubProps[i]] != 'undefined') {
			__pub[overPubProps[i]] = props[overPubProps[i]];
		}
	}

	// private vars
	var _par          = {};
	var _divId        = props.divId;
	var _pageLen      = props.pageLen;
	var _pageExpLen   = 0;
	var _pageNo       = 0;
	var _pageMax      = 0;
	var _pageRange    = [];
	var _pageId       = null;

	// private vars from the supplied props

	// private vars that have defaults but can be overidden

	// setup paging link onclick handlers
	sky.id(_divId + '_page_start').onclick = function(e) {_paginateStart();return false;};
	sky.id(_divId + '_page_lt').onclick    = function(e) {_paginateBack();return false;};
	sky.id(_divId + '_page_gt').onclick    = function(e) {_paginateForward();return false;};
	sky.id(_divId + '_page_end').onclick   = function(e) {_paginateEnd();return false;};

	var a;
	for (var i = 1; i <= 4; i++) {
		a = sky.id(_divId + '_page_' + i);
		a.page_idx = i;
		a.onclick = function(e) {_paginateGotoPage(e);return false;};
	}

function regPar(o) {

	_par = o;
}

// adjust the paginate start/end positions
function paginateAdjust() {

	var div = document.getElementById(_divId + '_page');
	var div_hide = document.getElementById(_divId + '_page_hide');

	// anything to display
	if (!_par.pub.items.length) {
		paginateHide();
		__pub.pageStart = 0;
		__pub.pageEnd   = 0;
		_pageNo = 0;
		return;
	}

	// changed id??
	var id = _par.pub.par.makeId();
	if (_pageId != id) {
		_pageId = id;
		__pub.pageEnd = 0;
	}

	// 1st time
	if (!__pub.pageEnd) {
		if (_pageLen > _par.pub.items.length) {
			__pub.pageEnd = _par.pub.items.length;
		} else {
			__pub.pageEnd = _pageLen;
		}
		__pub.pageStart = 0;
		_pageExpLen = _par.pub.items.length;

	// has the size of the list changed
	} else {

		if (_pageExpLen != _par.pub.items.length) {

			if (_pageExpLen < _par.pub.items.length) {
				__pub.pageEnd = __pub.pageStart + _pageLen;
				if (__pub.pageEnd > _par.pub.items.length) {
					__pub.pageEnd = _par.pub.items.length;
				}

			} else if (__pub.pageEnd > _par.pub.items.length) {
				__pub.pageEnd = _par.pub.items.length;
			}

			_pageExpLen = _par.pub.items.length;

			if (__pub.pageStart > __pub.pageEnd) {
				__pub.pageStart = 0;
				while (__pub.pageStart + _pageLen < __pub.pageEnd) {
					__pub.pageStart += _pageLen;
				}
			}
		}
	}

	// total pages
	_pageMax = Math.ceil(_par.pub.items.length / _pageLen);

	// show or hide the page-links
	if (_pageMax > 1) {
		_paginateShow();
	} else {
		paginateHide();
	}

	// setup page number
	_paginatePageNo();
}



// hide pagination
function paginateHide() {

	document.getElementById(_divId + '_page').style.display = 'none';
	document.getElementById(_divId + '_page_hide').style.display = '';
}



// show pagination
function _paginateShow() {

	document.getElementById(_divId + '_page').style.display = '';
	document.getElementById(_divId + '_page_hide').style.display = 'none';
}



// set the paginate page number
function _paginatePageNo() {

	var offset, p, ll, a;
	offset = 0;

	// what page are we on
	if (__pub.pageStart == 0) {
		_pageNo = 1;
	} else {
		_pageNo = (__pub.pageStart / _pageLen) + 1;
		if (_pageNo > 4) {
			if (_pageNo == _pageMax) {
				offset = 3;
			} else if (_pageNo + 1 == _pageMax) {
				offset = 2;
			} else {
				offset = 1;
			}
		} else {
			offset = 1
		}
	}

	// set the page ranges
	for (var i = 0; i < 4; i++) {
		p = !offset ? i + 1 : _pageNo + (i - offset);

		a = document.getElementById(_divId + '_page_' + (i + 1));

		if (p > _pageMax) {
			a.style.display = 'none';
		} else {
			a.style.display = '';
			a.innerHTML = p == _pageNo ? '<b>' + p + '</b>' : p;
		}

		_pageRange[i] = p;
	}
}


// paginate Start
function _paginateStart() {

	if (__pub.pageStart <= 0) {
		return;
	}

	__pub.pageStart = 0;
	if (_pageLen > _par.pub.items.length) {
		__pub.pageEnd = _par.pub.items.length;
	} else {
		__pub.pageEnd = _pageLen;
	}

	_par.pub.par.render();
}

// paginate back
function _paginateBack() {

	if (__pub.pageStart <= 0) {
		return;
	}

	__pub.pageEnd = __pub.pageStart;
	__pub.pageStart = __pub.pageStart - _pageLen;

	if (__pub.pageEnd > _par.pub.items.length) {
		__pub.pageEnd = _par.pub.items.length;
	}
	if (__pub.pageStart < 0) {
		__pub.pageStart = 0;
	}

	_par.pub.par.render();
}

// paginate forward
function _paginateForward() {

	if (__pub.pageEnd + 1 > _par.pub.items.length) {
		return;
	}

	__pub.pageStart = __pub.pageEnd;
	__pub.pageEnd = __pub.pageEnd + _pageLen;

	if (__pub.pageEnd > _par.pub.items.length) {
		__pub.pageEnd = _par.pub.items.length;
	}

	_par.pub.par.render();
}

// paginate End
function _paginateEnd() {

	if (__pub.pageEnd + 1 > _par.pub.items.length) {
		return;
	}

	__pub.pageStart = (_pageMax - 1) * _pageLen;
	__pub.pageEnd = __pub.pageStart + _pageLen;

	if (__pub.pageEnd > _par.pub.items.length) {
		__pub.pageEnd = _par.pub.items.length;
	}

	_par.pub.par.render();
}

// paginate goto-page
function _paginateGotoPage(e) {

	var pageIdx = e.target.page_idx;
	var page    = e.target.page;

	if (typeof page == 'undefined') {
		page = _pageRange[pageIdx - 1];
	}

	if (page == null) {
		return;
	}

	var start = (page - 1) * _pageLen;
	if (start > _par.pub.items.length || start < 0) {
		return;
	}

	__pub.pageStart = start;
	__pub.pageEnd = start + _pageLen;
	if (__pub.pageEnd > _par.pub.items.length) {
		__pub.pageEnd = _par.pub.items.length;
	}

	_par.pub.par.render();
}

	var _this = {
		pub : __pub,
		regPar : regPar,
		paginateAdjust : paginateAdjust,
		paginateHide : paginateHide
	};

	return _this;
}
