$.fn.dataTableExt.oPagination.fcbtv = {
  /*
   * Function: oPagination.fcbtv.fnInit
   * Purpose:  - not used for this implementation
   * Returns:  -
   * Inputs:   object:oSettings - dataTables settings object
   *           node:nPaging - the DIV which contains this pagination control
   *           function:fnCallbackDraw - draw function which must be called on update
   */
  "fnInit": function (oSettings, nPaging, fnCallbackDraw)
  {
  },

  /*
   * Function: oPagination.fcbtv.fnUpdate
   * Purpose:  Update pagination
   * Returns:  -
   * Inputs:   object:oSettings - dataTables settings object
   *           function:fnCallbackDraw - draw function which must be called on update
   */
  "fnUpdate": function ( oSettings, fnCallbackDraw )
  {

    var oClasses = oSettings.oClasses;

    // Get The Smallest of two values
    var smallest = function (a, b) {
      if (a < b) {
        return a;
      }
      return b;
    }

    // First Page Context
    var fpc = 1;

    // Current Page Left Context
    var cplc = 1;

    // Current Page Right Context
    var cprc = 1;

    // Last Page Content
    var lpc = 0;

    // Last Page
    var l = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);

    // First Page is 1
    var i = 1;

    // Current Page
    var c = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;

    var tmp = "";

    if (l <= i) {
      return "";
    }

    if (c > 1) {
      tmp += '<a href="#" class="Previous">&nbsp;</a>';
    } else {
      tmp += '<span class="Previous">&nbsp;</span>';
    }

    // First Page Context
    if (c > (fpc + cplc - 1)) {
      for (;i <= fpc;i++) {
        tmp += '<a class="Page" href="' + i + '">' + i + '</a>';
      }

      if (i < (c - cplc - 1)) {
        tmp += '<span style="float:left;margin-left:2px;margin-left:2px">&hellip;</span>';
      } else if (i < (c - cplc)) {
        tmp += '<a class="Page" href="' + i + '">' + i + '</a>';
      }
    }

    // Current Page Left Context
    if (i < (c - cplc)) {
      i = (c - cplc);
    }
    for (;i <= (c - 1);i++) {
      tmp += '<a class="Page" href="' + i + '">' + i + '</a>';
    }

    // Current Page
    tmp += '<span class="Active">' + c + '</span>';

    // Current Page Right Context
    for (i=c+1;i <= smallest(l, (c + cprc));i++) {
      tmp += '<a class="Page" href="' + i + '">' + i + '</a>';
    }

    // Last Context
    if (c < (l - (cprc + lpc))) {
      if (i < (l - lpc)) {
        tmp += '<span style="float:left;margin-left:2px;margin-left:2px">&hellip;</span>';
      }

      for (i=(l - lpc);i <= l;i++) {
        tmp += '<a class="Page" href="' + i + '">' + i + '</a>';
      }
    }
    if (c < l) {
      tmp += '<a href="' + i + '" class="Next">&nbsp;</a>';
    } else {
      tmp += '<span class="Next">&nbsp;</span>';
    }

    var an = oSettings.aanFeatures.p;

    for ( i=0, iLen=an.length ; i<iLen ; i++ ) {
      $(an[i]).html(tmp);
      $('a.Previous', an[i]).click(function() {
          if (oSettings.oApi._fnPageChange(oSettings, "previous")) {
            fnCallbackDraw(oSettings);
          }
          return false;
      });
      $('a.Next', an[i]).click(function() {
          if (oSettings.oApi._fnPageChange(oSettings, "next")) {
            fnCallbackDraw(oSettings);
          }
          return false;
      });
      $('a.Page', an[i]).click(function() {
          var iTarget = (this.innerHTML * 1) - 1;
          oSettings._iDisplayStart = iTarget * oSettings._iDisplayLength;
          fnCallbackDraw(oSettings);
          return false;
      });
    }
  }
};

