// BEGIN

  // ========================================== wbw Pager -- V 0.93
 //
//   (c) 2006 by ./o  this is free software. you may use it or not.


  // ========== Core and static methods ==========
 //
//


 // ----- translate user's html to browser's html
//
var wbwPagerTranslator = new Array();

function wbwPagerRegisterTranslator(nodetype, childtype, objecttype) {
    var translator = new Array;

    translator['childtype'] = childtype;
    translator['objecttype'] = objecttype;

    wbwPagerTranslator[nodetype] = translator;
}

function _wbwPagerGetTranslator(aNode) {
    var translator = wbwPagerTranslator[aNode.nodeName];
    if (translator == null) {
	translator = wbwPagerTranslator['*'];
    }

    return translator;
}

wbwPagerRegisterTranslator('TABLE', 'TBODY', 'TR')
wbwPagerRegisterTranslator('TR', null, 'TD')
wbwPagerRegisterTranslator('OL', null, 'LI');
wbwPagerRegisterTranslator('UL', null, 'LI');
wbwPagerRegisterTranslator('*', null, null)

// ----- U may add translations by our own!




  // ========== core object ==========
 //
//
var wbwPager = new Array();





  // ========== setup & basics  ==========
 //
//

 // ---- robber childs (done by html translator)
//
function _wbwPagerGetChildHolder(aNode) {
    var translator = _wbwPagerGetTranslator(aNode);

    var nodeWithChilds = aNode;

    if (translator['childtype'] != null)
    {
	    for (var i=0; i<nodeWithChilds.childNodes.length; i++)
	    {
	      if (nodeWithChilds.childNodes[i].nodeName == translator['childtype'])
	      {
		      nodeWithChilds = nodeWithChilds.childNodes[i];
		      break;
	      }
	    }
    }

    return nodeWithChilds;
}


 // ----- sort callbacks
//
function ___wbwPagerSortNumCb(a,b) {return a-b;}
function ___wbwPagerSortINumCb(a,b) {return b-a;}
function ___wbwPagerSortStrCb(a,b) {return (a>b ? 1 : (a<b ? -1 : 0));}
function ___wbwPagerSortIStrCb(a,b) {return (a>b ? -1 : (a<b ? 1 : 0));}
function ___wbwPagerSortDateCb(a,b) {a=new Date(a); b=new Date(b); return a.getTime()-b.getTime();}
function ___wbwPagerSortIDateCb(a,b) {a=new Date(a); b=new Date(b); return b.getTime()-a.getTime();}
function ___wbwPagerFilterEqCb(element, pagerId, orderId, value) {
    return element.getAttribute(pagerId + '.' + orderId) == value;
}
function ___wbwPagerFilterMatchCb(element, pagerId, orderId, value) {
    try {
	var attribute = element.getAttribute(pagerId + '.' + orderId);
	return attribute.search(value) >= 0;
    }
    catch (e) {
	return false;
    }
}


function ___wbwPagerGetSortCb(sortedBy) {
    if (sortedBy == null) {
	sortedBy = ___wbwPagerSortStrCb;
    }
    else {
	if (typeof(sortedBy) != 'function') {
	    switch (sortedBy) {
	    case '+date':
	    case 'date':
		sortedBy = ___wbwPagerSortDateCb;
		break;

	    case '-date':
		sortedBy = ___wbwPagerSortIDateCb;
		break;

	    case '+number':
	    case 'number':
		sortedBy = ___wbwPagerSortNumCb;
		break;

	    case '-number':
		sortedBy = ___wbwPagerSortINumCb;
		break;

	    case '-string':
		sortedBy = ___wbwPagerSortIStrCb;
		break;

	    case '+string':
	    case 'string':
	    default:
		sortedBy = ___wbwPagerSortStrCb;
		break;
	    }
	}
    }

    return sortedBy;
}


  // ========== translocation =====
 //
//

 // ----- display this pager object
//
function __wbwPagerDraw(pager, event) {

    // ----- first delete existing nodes
    //
    while (pager['itemHolder'].hasChildNodes()) {
	pager['itemHolder'].removeChild(pager['itemHolder'].firstChild);
    }

    var usedOrder = pager['order'][pager['usedOrder']];

    var nextToAdd = pager['pos'];
    if (nextToAdd >= usedOrder.length) { // could 'never' happen! :-)
	__wbwPagerSetPos(pager, 0);
	nextToAdd = 0;
    }

    var maxOnPage = pager['pos'] + pager['noOfItemsPerPage'];
    if (maxOnPage > usedOrder.length) {
	maxOnPage = usedOrder.length;
    }


    pager['firstItemOnPage'] = null;

    for (var i=0; i<pager['headerItems'].length; i++) {
	pager['itemHolder'].appendChild(pager['headerItems'][i]);
    }
    while (nextToAdd < maxOnPage) {
	pager['lastItemOnPage'] = usedOrder[nextToAdd].cloneNode(true);
	if (pager['firstItemOnPage'] == null) {
	    pager['firstItemOnPage'] = pager['lastItemOnPage'];
	}

	pager['itemHolder'].appendChild(pager['lastItemOnPage']);
	nextToAdd++;
    }
    if (pager['firstItemOnPage'] == null) {
	for (var i=0; i<pager['defaultItems'].length; i++) {
	    pager['itemHolder'].appendChild(pager['defaultItems'][i]);
	}
    }
    for (var i=0; i<pager['footerItems'].length; i++) {
	pager['itemHolder'].appendChild(pager['footerItems'][i]);
    }

    pager['noOfItemsShownOnPage'] = nextToAdd - pager['pos'];
    pager['lastPosOnPage'] = nextToAdd - 1;

    if (event != null) {
	__wbwPagerHandleEvent(pager, event);
    }
}


 // ----- forward
//
function __wbwPagerForward(pager, steps, preventPageSize) {
    var usedOrder = pager['order'][pager['usedOrder']];
    if (pager['pos'] + steps >= usedOrder.length) {
	return;
    }
    if (preventPageSize == null) {
	preventPageSize = pager['preventPageSize'];
    }

    if (preventPageSize) {
	if ((pager['pos'] + steps) >= (usedOrder.length - pager['noOfItemsPerPage'])) {
	    steps = (usedOrder.length - pager['pos']) - pager['noOfItemsPerPage'];
	}
    }

    __wbwPagerSetPos(pager, pager['pos'] + steps)
    __wbwPagerDraw(pager, 'repos');
}


 // ----- backward
//
function __wbwPagerBackward(pager, steps) {
    if (pager['pos'] == 0) {
	return;
    }

    if (pager['pos'] - steps < 0) {
	__wbwPagerSetPos(pager, 0);
    }
    else {
	__wbwPagerSetPos(pager, pager['pos'] - steps);
    }

    __wbwPagerDraw(pager, 'repos');
}


 // ----- jump
//
function __wbwPagerJump(pager, pos, preventPageSize) {
    var usedOrder = pager['order'][pager['usedOrder']];
    if (pos < 0) {
	pos = usedOrder.length + pos;
    }
    if (pos >= usedOrder.length) {
	pos = usedOrder.length - pager['noOfItemsPerPage'];
    }
    if (pos < 0) {
	pos = 0;
    }

    if (pager['pos'] == pos) {
	return;
    }

    if (preventPageSize == null) {
	preventPageSize = pager['preventPageSize'];
    }

    if (preventPageSize) {
	if (pos + pager['noOfItemsPerPage'] >= usedOrder.length) {
	    pos = usedOrder.length - pager['noOfItemsPerPage'];
	}
    }

    __wbwPagerSetPos(pager, pos);
    __wbwPagerDraw(pager, 'repos');
}


function __wbwPagerSetPos(pager, value) {
    pager['pos'] = value;
}



  // ========== Toggle, event and message handling ==========
 //
//

 // ----- translate events to messages and toggles
//
function __wbwPagerHandleEvent(pager, event) {
    switch (event) {
    case 'resize':
	__wbwPagerMessage(pager, 'noOfItemsPerPage', pager['noOfItemsPerPage']);
	__wbwPagerHandlePageToggles(pager, false);
	break;

    case 'enlarge':
	__wbwPagerHandleEvent(pager, 'resize');
	break;

    case 'shrink':
	__wbwPagerHandleEvent(pager, 'resize');
	break;

    case 'reverseOrder':
	__wbwPagerToggle(pager, 'reverseOrder', pager['orderReverseActive']);
	break;

    case 'filterOrder':
	__wbwPagerToggle(pager, 'filterOrder', pager['orderFilterActive']);
	__wbwPagerMessage(pager, 'noOfItemsShown', pager['order'][pager['usedOrder']].length);
	__wbwPagerToggle(pager, 'noOfItemsShownIsOne', pager['noOfItems'] == 1);
	__wbwPagerHandleEvent(pager, 'repos');
	break;

    case 'repos':
	__wbwPagerHandlePageToggles(pager, false);
	__wbwPagerMessage(pager, 'firstPosOnPage', pager['pos']);
	__wbwPagerMessage(pager, 'lastPosOnPage', pager['lastPosOnPage']);
	__wbwPagerMessage(pager, 'noOfItemsShownOnPage', pager['noOfItemsShownOnPage']);
	__wbwPagerToggle(pager, 'noOfItemsShownOnPageIsOne', pager['noOfItems'] == 1);
	__wbwPagerMessage(pager,
			  'firstItemOnPage',
			  pager['firstItemOnPage'].getAttribute(pager['orderAttribute']));
	__wbwPagerMessage(pager,
			  'lastItemOnPage',
			  pager['lastItemOnPage'].getAttribute(pager['orderAttribute']));
	break;

    case 'reorder':
    case 'init':
	__wbwPagerHandleEvent(pager, 'filterOrder');
	__wbwPagerHandleEvent(pager, 'reverseOrder');
	__wbwPagerHandleEvent(pager, 'resize');
	__wbwPagerMessage(pager, 'usedOrder', pager['orderName']);
	__wbwPagerMessage(pager, 'noOfItems', pager['noOfItems']);
	__wbwPagerToggle(pager, 'noOfItemsIsOne', pager['noOfItems'] == 1);
	__wbwPagerMessage(pager,
			  'noOfItemsShown',
			  pager['order'][pager['usedOrder']].length);
	break;

    }
}


 // -----
//
function __wbwPagerHandlePageToggles(pager, enforce) {
    __wbwPagerToggle(pager,
		     'firstItemIsShown',
		     (pager['noOfItemsShownOnPage'] > 0) && (pager['pos'] == 0));

    __wbwPagerToggle(pager,
		     'lastItemIsShown',
		     (pager['noOfItemsShownOnPage'] > 0) &&
		     (pager['lastPosOnPage'] + 1 == pager['order'][pager['usedOrder']].length));
}




 // ----- the default message handler
//
function ___wbwPagerMessageCb(nodeId, text) {
    var node = document.getElementById(nodeId);
    if (node == null) {
	// CCC: throw?
	return;
    }

    if (node.hasChildNodes()) {
	if (node.firstChild.nodeType == 3) {
	    node.firstChild.data = text;
	}
	else {
	    // CCC; throw?
	}
    }
    else {
	node.appendChild(document.createTextNode(text));
    }
}


 // ----- pass a message to a node
//
function __wbwPagerMessage(pager, slot, text) {
    var msgSlot = pager['msgSlot'][slot];

    if (msgSlot == null) {
	return;
    }

    for (var nodeId in msgSlot) {
	msgSlot[nodeId](nodeId, text);
    }
}


 // ----- set toggle to correct state
//
function __wbwPagerToggle(pager, slot, onOrOff) {
    var toggleSlot = pager['toggleSlot'][slot];

    if (toggleSlot == null) {
	return;
    }

    for (var nodeId in toggleSlot) {
	var toggleData = toggleSlot[nodeId];

	toggleData['handler'](nodeId,
			      onOrOff,
			      toggleData['onValue'],
			      toggleData['offValue']);
    }
}


 // ----- toggle implementations
//

function ___wbwPagerToggleClassCb(nodeId, onOrOff, classNameOn, classNameOff) {
    var node = document.getElementById(nodeId);

    if (node == null) {
	return;
    }

    var classAttribute = node.getAttribute('class');
    if (classAttribute == null) {
	classAttribute = '';
    }
    var currentClasses = classAttribute.split(' ');
    var classToUse = new Array;

    var wanted = (onOrOff ? classNameOn : classNameOff);
    var unwanted = (onOrOff ? classNameOff : classNameOn);

    classToUse.push(wanted);

    for (var i=0; i<currentClasses.length; i++) {
	if ((currentClasses[i] != wanted) && (currentClasses[i] != unwanted)) {
	    classToUse.push(currentClasses[i]);
	}
    }

    node.setAttribute('class', classToUse.join(' '));
}

function ___wbwPagerToggleTextCb(nodeId, onOrOff, textOn, textOff) {
    ___wbwPagerMessageCb(nodeId, onOrOff ? textOn : textOff);
}



  // ========== filter & reverse ==========
 //
//


 // ----- unset filter
//
function __wbwPagerDeactiveFilter(pager) {
    if (pager['orderFilterActive']) {
	pager['orderFilterActive'] = false;

	if (pager['orderReverseActive']) {
	    pager['usedOrder'] = pager['orderName'] + ':reverse';
	}
	else {
	    pager['usedOrder'] = pager['orderName'];
	}

	__wbwPagerHandleEvent(pager, 'filterOrder');
    }

    __wbwPagerSetPos(pager, 0);
    __wbwPagerDraw(pager, 'repos');
}



 // ----- set filter
//
function __wbwPagerActivateFilter(pager, filterCallback, pagerId, orderId, value) {
    var orderName = pager['orderName'] + ':filter';

    pager['order'][orderName] = new Array;

    if (orderId == null) {
	orderId = pager['orderName']; // this is not very usefull
    }

    if (typeof(filterCallback) == 'string') {
	switch (filterCallback) {
	case 'match':
	    filterCallback = ___wbwPagerFilterMatchCb;
	    break;

	case 'eq':
	default:
	    filterCallback = ___wbwPagerFilterEqCb;
	    break;
	}
    }

    for (var i=0; i<pager['order'][pager['orderName']].length; i++) {
	if (filterCallback(pager['order'][pager['orderName']][i],
			   pagerId,
			   orderId,
			   value)) {
	    pager['order'][orderName].push(pager['order'][pager['orderName']][i]);
	}
    }

    if (pager['orderReverseActive']) {
	var reverseOrderName = orderName + ':reverse';
	pager['order'][reverseOrderName] = new Array;

	for (var i=pager['order'][orderName].length - 1; i>=0; i--) {
	    pager['order'][reverseOrderName].push(pager['order'][orderName][i]);
	}

	pager['usedOrder'] = reverseOrderName;
    }
    else {
	pager['usedOrder'] = orderName;
    }


    if (! pager['orderFilterActive']) {
	pager['orderFilterActive'] = true;
	__wbwPagerHandleEvent(pager, 'filterOrder');
    }

    __wbwPagerSetPos(pager, 0);
    __wbwPagerDraw(pager, 'repos');
}





  // ========================================== member
 //
//
//
//  pagerNodeId              id of node to be paged. Is ^itemHolder or father
//                            of ^itemHolder
//  pagerNode                node with id ^pagerNodeId
//
//  items                    array of item nodes in native order as got
//                             from source
//  defaultItems             array if item nodes to be displayed if
//                             ^order[^usedOrder] is empty
//  headerItems              array if item nodes to be always displayed as header
//  footerItems              array if item nodes to be always displayed as footer
//
//  itemHolder               node where to insert item nodes, is ^pageNode or
//                             son of ^pageNode.
//
//  noOfItems                number of item nodes (~ ^ítems.length) (attention:
//                            ^order[^usedOrder].length is the number of items
//                            that MAY be shown (an order may be filtered!))
//  noOfItemsPerPage         no of items on page
//  noOfItemsPerPageDefault  default value as got in constructor
//
//  noOfItemsShownOnPage     number of items currently display (only set if
//
//
//  pos                      first element shown respective to array
//                            ^order[^usedOrder]
//  order                    hash(#ORDER) of arrays of item nodes to be
//                            shown if order #ORDER is used
//  usedOrder                name #ORDER of currently used order (may be
//                            either a master or an artificial order)
//
//  orderName                the name of the master order (:filter, :reverse
//                             and :filter:reverse are artificial)
//  orderFilterActive        is set if :filter order is active
//  orderReverseActive       is set if :reverse order is active
//  orderAttribute           attribute of item nodes to get item name
//
//
//  lastItemOnPage           last item node shown on page after activation
//  lastPosOnPage            last pos node shown on page after activation
//
//  firstItemOnPage          first item node shown on page after activation
//  firstPosOnPage           first pos shown on page after activation
//
//
//  msgSlot                  hash(#event) of hash message and event handler.
//  toggleSlot               hash(#event) of hash message and event handler.
//
//  preventPageSize          if set to 'true' (the default) ^noOfItemsPerPage
//                            items are always shown. if set to 'false', a
//                            forward operation may decrease no of shown items
//                            if ^pos > ^order[^usedOrder]^length - ^noOfItemsPerPage
//
//  minPageSize              1
//  maxPageSize              10
//
//
//
function wbwPagerCreate(pagerId, noOfItemsPerPage) {

     // ----- check if programmer is a nanosoftler
    //
    if (wbwPager[pagerId] != null) {
	throw('wbw pager: cannot create pager [' + pagerNode + '] twice');
	return null;
    }

     // ----- check if node exists and are compatible
    //
    var pagerNode = document.getElementById(pagerId);
    if (pagerNode == null) {
	throw('wbw pager: cannot locate pager node [' + pagerNode + ']');
	return null;
    }


     // ----- create object
    //
    var pager = new Array;
    pager['pagerNode'] = pagerNode;
    pager['pagerNodeId'] = pagerId;


     // ----- organize items
    //
    pager['items'] = new Array;

    pager['preventPageSize'] = true;
    pager['itemHolder'] = _wbwPagerGetChildHolder(pagerNode);

    pager['defaultItems'] = new Array;
    pager['headerItems'] = new Array;
    pager['footerItems'] = new Array;



    var translator = _wbwPagerGetTranslator(pagerNode);

    while (pager['itemHolder'].hasChildNodes()) {
	var pushIt = pager['items'];

	  if (translator['objecttype'] != null)
	  {
	    if (translator['objecttype'] != pager['itemHolder'].firstChild.nodeName)
	    {
		    pushIt = null;
	    }
	    else
	    {
		    var itemType = pager['itemHolder'].firstChild.getAttribute(pagerId);

        switch (itemType)
        {
          case 'default':
              pushIt = pager['defaultItems'];
              break;

          case 'header':
              pushIt = pager['headerItems'];
              break;

          case 'footer':
              pushIt = pager['footerItems'];
              break;
        }
      }
	  }

	if (pushIt) {
	    pushIt.push(pager['itemHolder'].firstChild.cloneNode(true));
	}

	pager['itemHolder'].removeChild(pager['itemHolder'].firstChild);
    }


    if (pager['items'] == null) {
	throw('wbw pager: no items at pager node [' + pagerNode + ']');
	return null;
    }



    var order = pager['order'] = new Array;

    order['native'] = new Array;

    for (var i=0; i<pager['items'].length; i++) {
	order['native'][i] = pager['items'][i];

	pager['items'][i].setAttribute(pagerId + '.native', i+1);
    }


    // ----- setup objects
    //
    pager['usedOrder'] = 'native';


    // ----- the masterOrder
    //
    pager['orderName'] = 'native';
    pager['orderAttribute'] = pagerId + '.native';
    pager['orderFilterActive'] = false;
    pager['orderReverseActive'] = false;


    pager['noOfItems'] = pager['items'].length;
    if (noOfItemsPerPage == null) {
	noOfItemsPerPage = pager['noOfItems'];
    }

    pager['noOfItemsPerPage'] = noOfItemsPerPage;
    pager['noOfItemsPerPageDefault'] = noOfItemsPerPage;

    pager['noOfItemsShownOnPage'] = null;
    pager['firstItemOnPage'] = null;
    pager['lastItemOnPage'] = null;


     // ----- message & toggle handler
    //
    pager['msgSlot'] = new Array;
    pager['toggleSlot'] = new Array;


    // do not call __wbwPagerSetPos(pager, 0) here!!
    pager['pos'] = 0;


    // ----- finally register object in core
    //
    wbwPager[pagerId] = pager;

    return pager;
}


function wbwPagerPreventPageSize (pagerId, prevent) {
    var pager = wbwPager[pagerId];

    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    pager['preventPageSize'] = prevent;
}



  // ========== registrations ==========
 //
//

function wbwPagerRegisterOrder(pagerId, orderName, sortedBy) {
    var pager = wbwPager[pagerId];

    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    if (pager['order'][orderName] != null) {
	throw('wbw pager:  pager [' + pagerNode + '] order [' +
	      orderName +  ' already exists');
    }


     // ----- read in order attributes (must exists, prepare to handle dublicates)
    //
    var toBeSorted = new Array;
    var resortAttributes = new Array;
    for (var i=0; i<pager['items'].length; i++) {
	var attribute = pager['items'][i].getAttribute(pagerId + '.' + orderName);

	if (attribute == null) {
	    throw('wbw pager:  pager [' + pagerNode + '] child #[' + i +
		  ' does not have attribute [' + pagerId + '.' + orderName + ']');
	}

	toBeSorted[i] = attribute;


	if (resortAttributes[attribute] == null) {
	    resortAttributes[attribute] = new Array;
	}
	resortAttributes[attribute].push(i);
    }


    try {
	sortedBy = ___wbwPagerGetSortCb(sortedBy);
	toBeSorted.sort(sortedBy);
    }
    catch (e) {
	throw('wbw pager:  pager [' + pagerNode + '] order [' +
	      orderName +  ' sort attributes failed [' + e + ']');
    }


    var newOrder = pager['order'][orderName] = new Array;
    for (var i=0; i<toBeSorted.length; i++) {
	newOrder.push(pager['items'][resortAttributes[toBeSorted[i]].shift()]);
    }


}


function wbwPagerRegisterMessageNode(pagerId,
				     messageType,
				     nodeId, messageHandler) {
    var pager = wbwPager[pagerId];

    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    if (pager['msgSlot'][messageType] == null) {
	pager['msgSlot'][messageType] = new Array;
    }

    if (nodeId == null) {
	nodeId = pager['pagerNodeId'] + '.' + messageType;
    }

    if (messageHandler == null) {
	messageHandler = ___wbwPagerMessageCb;
    }
    else {
	if (typeof(messageHandler) != 'function') {
	    switch (messageHandler) {
	    default:
		messageHandler = ___wbwPagerMessageCb;
		break;
	    }
	}
    }

    pager['msgSlot'][messageType][nodeId] = messageHandler;
}


function wbwPagerRegisterToggleNode(pagerId,
				    toggleType, onValue, offValue,
				    nodeId, toggleHandler) {
    var pager = wbwPager[pagerId];

    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    if (pager['toggleSlot'][toggleType] == null) {
	pager['toggleSlot'][toggleType] = new Array;
    }

    if (nodeId == null) {
	nodeId = pager['pagerNodeId'] + '.' + toggleType;
    }

    if (toggleHandler == null) {
	toggleHandler = ___wbwPagerToggleTextCb;
    }
    else {
	if (typeof(toggleHandler) != 'function') {
	    switch(toggleHandler) {
	    case 'class':
		toggleHandler = ___wbwPagerToggleClassCb;
		break;
	    case 'text':
	    default:
		toggleHandler = ___wbwPagerToggleTextCb;
		break;
	    }
	}
    }

    var toggleData = new Array;
    toggleData['handler'] = toggleHandler;
    toggleData['onValue'] = onValue;
    toggleData['offValue'] = offValue;

    pager['toggleSlot'][toggleType][nodeId] = toggleData;
}


function wbwPagerActivate(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    __wbwPagerDraw(pager, 'init');
}





  // ========== select reverse ==========
 //
//

function wbwPagerToggleReverse(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    var usedOrder = pager['order'][pager['usedOrder']];

    if (pager['orderFilterActive']) {
	if (pager['orderReverseActive']) {
	    pager['orderReverseActive'] = false;
	    pager['usedOrder'] = pager['orderName'] + ':filter';
	}
	else {
	    pager['orderReverseActive'] = true;
	    pager['usedOrder'] = pager['orderName'] + ':filter:reverse';

	    if (pager['order'][pager['usedOrder']] == null) {
		pager['order'][pager['usedOrder']] = new Array;

		for (var i=usedOrder.length-1; i>=0; i--) {
		    pager['order'][pager['usedOrder']].push(usedOrder[i]);
		}
	    }
	}
    }
    else {
	if (pager['orderReverseActive']) {
	    pager['orderReverseActive'] = false;
	    pager['usedOrder'] = pager['orderName'];
	}
	else {
	    pager['orderReverseActive'] = true;
	    pager['usedOrder'] = pager['orderName'] + ':reverse';

	    if (pager['order'][pager['usedOrder']] == null) {
		pager['order'][pager['usedOrder']] = new Array;

		for (var i=usedOrder.length-1; i>=0; i--) {
		    pager['order'][pager['usedOrder']].push(usedOrder[i]);
		}
	    }
	}
    }

    var pos = usedOrder.length - pager['pos'] - pager['noOfItemsPerPage'];
    if (pos < 0) {
	pos = 0;
    }

    __wbwPagerSetPos(pager, pos);
    __wbwPagerHandleEvent(pager, 'reverseOrder');
    __wbwPagerDraw(pager, 'repos');
}


  // ========== select filter ==========
 //
//


 // ----- toggle
//
function wbwPagerToggleFilter(pagerId, filterCallback, orderId, value) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }


    if (filterCallback == null || pager['orderFilterActive']) {
	__wbwPagerDeactiveFilter(pager);
	return;
    }

    __wbwPagerActivateFilter(pager, filterCallback, pagerId, orderId, value);

    return;
}


 // ----- unset
//
function wbwPagerUnsetFilter(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    __wbwPagerDeactiveFilter(pager);
}


 // ----- set
//
function wbwPagerSetFilter(pagerId, filterCallback, orderId, value) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    __wbwPagerActivateFilter(pager, filterCallback, pagerId, orderId, value);
}



  // ========== select order ==========
 //
//

function wbwPagerUseOrder(pagerId, orderName) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    var order = wbwPager[pagerId]['order'][orderName];
    if (order == null) {
	throw('wbw pager: invalid order [' + orderName +
	      '] for pager id [' + pagerId + ']');
    }

    if (pager['orderReverseActive']) {
	pager['orderReverseActive'] = false;
	__wbwPagerHandleEvent(pager, 'reverseOrder');
    }
    if (pager['orderFilterActive']) {
	pager['orderFilterActive'] = false;
	__wbwPagerHandleEvent(pager, 'filterOrder');
    }

    pager['orderName'] = orderName;
    pager['usedOrder'] = orderName;
    pager['orderAttribute'] = pagerId + '.' + orderName;

    __wbwPagerDraw(pager, 'reorder');
}



  // ========================================== move per page
 //
//
function wbwPagerNextPage(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    __wbwPagerForward(pager, pager['noOfItemsPerPage']);
}

function wbwPagerPrevPage(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    __wbwPagerBackward(pager, pager['noOfItemsPerPage']);
}

function wbwPagerLastPage(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    __wbwPagerJump(pager, - pager['noOfItemsPerPage']);
}

function wbwPagerFirstPage(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    __wbwPagerJump(pager, 0);
}



  // ========================================== move per Element
 //
//

function wbwPagerNextElement(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    __wbwPagerForward(pager,  1);
}

function wbwPagerPrevElement(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    __wbwPagerBackward(pager, 1);
}

function wbwPagerLastElement(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    __wbwPagerJump(pager, -1);
}

function wbwPagerFirstElement(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }
    __wbwPagerJump(pager, 0);
}




  // ========================================== manipulate view
 //
//
function wbwPagerIncrNoOfItems(pagerId, steps) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    var usedOrder = pager['order'][pager['usedOrder']];

    var newNoOfItemsPerPage = pager['noOfItemsPerPage'] + steps;
    if (newNoOfItemsPerPage > usedOrder.length) {
	newNoOfItemsPerPage = usedOrder.length;
    }

    if (pager['noOfItemsPerPage'] != newNoOfItemsPerPage) {
	pager['noOfItemsPerPage'] = newNoOfItemsPerPage;

	if (pager['pos'] > usedOrder.length - newNoOfItemsPerPage) {
	    __wbwPagerBackward(pager, 1);
	    __wbwPagerHandleEvent(pager, 'enlarge');
	}
	else {
	    __wbwPagerDraw(pager, 'enlarge');
	}
    }
}

function wbwPagerDecrNoOfItems(pagerId, steps) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    var newNoOfItemsPerPage = pager['noOfItemsPerPage'] - steps;
    if (newNoOfItemsPerPage < 1) {
	newNoOfItemsPerPage = 1;
    }

    if (pager['noOfItemsPerPage'] != newNoOfItemsPerPage) {
	pager['noOfItemsPerPage'] = newNoOfItemsPerPage;
	__wbwPagerDraw(pager, 'shrink');
    }
}

function wbwPagerReset(pagerId) {
    var pager = wbwPager[pagerId];
    if (pager == null) {
	throw('wbw pager: invalid pager id [' + pagerId + ']');
    }

    if (pager['noOfItemsPerPage'] != pager['noOfItemsPerPageDefault']) {
	pager['noOfItemsPerPage'] = pager['noOfItemsPerPageDefault'];
	__wbwPagerHandleEvent(pager, 'resize');
    }

    __wbwPagerSetPos(pager, 0);

    if (pager['orderReverseActive']) {
	pager['orderReverseActive'] = false;
	pager['usedOrder'] = pager['orderName'];
	__wbwPagerHandleEvent(pager, 'reverseOrder');
    }
    if (pager['orderFilterActive']) {
	pager['orderFilterActive'] = false;
	pager['usedOrder'] = pager['orderName'];
	__wbwPagerHandleEvent(pager, 'filterOrder');
    }

    __wbwPagerDraw(pager, 'repos');
}


// END