var iterate = require('./lib/iterate.js')

, initState  = require('./lib/state.js')
, terminator = require('./lib/terminator.js')
;

// Public API module.exports = serialOrdered; // sorting helpers module.exports.ascending = ascending; module.exports.descending = descending;

/**

* Runs iterator over provided sorted array elements in series
*
* @param   {array|object} list - array or object (named list) to iterate over
* @param   {function} iterator - iterator to run
* @param   {function} sortMethod - custom sort function
* @param   {function} callback - invoked when all elements processed
* @returns {function} - jobs terminator
*/

function serialOrdered(list, iterator, sortMethod, callback) {

var state = initState(list, sortMethod);

iterate(list, iterator, state, function iteratorHandler(error, result)
{
  if (error)
  {
    callback(error, result);
    return;
  }

  state.index++;

  // are we there yet?
  if (state.index < (state['keyedList'] || list).length)
  {
    iterate(list, iterator, state, iteratorHandler);
    return;
  }

  // done here
  callback(null, state.results);
});

return terminator.bind(state, callback);

}

/*

* -- Sort methods
*/

/**

* sort helper to sort array elements in ascending order
*
* @param   {mixed} a - an item to compare
* @param   {mixed} b - an item to compare
* @returns {number} - comparison result
*/

function ascending(a, b) {

return a < b ? -1 : a > b ? 1 : 0;

}

/**

* sort helper to sort array elements in descending order
*
* @param   {mixed} a - an item to compare
* @param   {mixed} b - an item to compare
* @returns {number} - comparison result
*/

function descending(a, b) {

return -1 * ascending(a, b);

}