/* ------------------------------------------------------------------------- */

$(document).ready( 
  function start ()
  {
    setupLoadingIcon()
    installCollapsers()
    installOptions()
    installEnters()
    installSmartFields()
    installHandlers()
    index()
    readCustomSetting()
    setupBrowserHistory()
    updateAuth()
  }
)

function index ()
{
  // When no document is requested using the resource hash, open the index
  // document by default.
  //alert("address=" + $.address.value())
  if (!$.address.value() || $.address.value() == '/') $.address.value('Index')
}

function setupBrowserHistory ()
{
  // History changes are reflected using the parseURI/update functions.
  $.address.change(
    function historyChange (evt)
    {
      parseURI(evt)
      update()
    }
  )
}

function cursor_wait() {
  document.body.style.cursor = 'wait';
}

function cursor_clear() {
  document.body.style.cursor = 'default';
}

function setupLoadingIcon ()
{
  $("#loading").ajaxStart(
    function ()
    {
       cursor_wait();
       $(this).show();
    }
  );
  $("#loading").ajaxStop(
    function ()
    {
       cursor_clear()
       $(this).hide();
    }
  ); 
}

function installHandlers ()
{
  $('#whatsnew-btn').click(showWhatsnew)
  $('#format-btn').click(showCustomizer)
  $('#history-btn').click(showHistory)
  $('#edit-btn').click(showEditor)
  $('#login-btn').click(login)
  $('#logout-btn').click(logout)
  $('#create-account-btn').click(signup)
  $('#preview-btn').click(preview)
  $('#removespace-btn').click(remove_space)
  $('#insertbreak-btn').click(insert_break)
  // $('#rename-btn').click(rename)
  // $('#delete-btn').click(_delete)
  // $('#search-btn').click(search)
  $('#search-prev-btn').click(searchPrev)
  $('#search-next-btn').click(searchNext)
  $('#smaller-btn'). click(fontsizedown)
  $('#larger-btn'). click(fontsizeup)
}

/* ------------------------------------------------------------------------- */

// Current application state.

Wiki = {

  // Static information.
    prefix     : 'data/'
  , titleStr   : ' - 亿年书海 - 电子书 wiki 网'
  , checkURI   : 'check/'
  , previewURI : 'preview/'
  , searchURI  : 'search/'
  , loginURI   : 'login'
  , logoutURI  : 'logout'
  , loginfoURI : 'loginfo'
  , signupURI  : 'signup'
  , viewerURI  : '/'

  // State information.
  , title      : ''
  , path       : ''
  , ext        : 'html'
  , rev        : ''
  , anchor     : ''
  , url        : ''

  , prevTitle  : ''
  , prevExt    : ''
  , prevRev    : ''
  , prevAnchor : ''

  , author     : ''
  , user       : ''

  , search     : {
      results : []
    , max     : 40
    , index   : 0
  }
  , historyPageSize : 10 
}

function parseURI (evt)
{
  //alert("parseURI got " + evt.path)
  var path = decodeURI(evt.path)
  var ext = path.match(/\.([^.]*)$/)
  var tit = path.match(/^\/(.*)\.([^.]*)$/)

  Wiki.prevTitle  = Wiki.title
  Wiki.prevExt    = Wiki.ext
  Wiki.prevRev    = Wiki.rev
  Wiki.prevAnchor = Wiki.anchor

  Wiki.title  = tit ? tit[1] : path.substr(1) 
  Wiki.ext    = ext ? ext[1] : 'html'
  Wiki.rev    = evt.parameters.r
  Wiki.anchor = evt.parameters.a
  Wiki.path   = path + "?r=" + Wiki.rev 
  $.address.title(Wiki.title + Wiki.titleStr)
  //alert(Wiki.title + "," + Wiki.ext+ "," +Wiki.rev+ "," +Wiki.anchor)
  if (jQuery.browser.msie)
  {
    Wiki.url = window.location.href.substring(0, window.location.href.length - window.location.hash.length)
    //alert("url = " + Wiki.url)
  }
  // check whether we shall inherit rev ID from previous doc
  var maindoc = dirname(Wiki.title)
  if (Wiki.rev === undefined && dirname(Wiki.prevTitle) == maindoc && maindoc != "")
  {
     Wiki.rev = Wiki.prevRev
  } 
}

function dirname(path) {
  return path.replace(/\\/g,'/').replace(/\/[^\/]*$/, '');;
}

function update ()
{
  var t = 0
  var i, s
  // Only refresh when one of these change.
  if (Wiki.title != Wiki.prevTitle ||
      Wiki.ext   != Wiki.prevExt   ||
      Wiki.rev   != Wiki.prevRev) {

    // Update information bar.
    $('#document').html(Wiki.title)
    $('#revision').html(Wiki.rev || '<i>最新版本</i>')
    // $('#user').html(Wiki.user)
    // cache_scroll()
    i = cache_guess(Wiki.path)
    if (i == -1) s = cache_backward()
    else if (i == 1) s = cache_forward()
    if (s) 
    {
      var x = document.all ? document.body.scrollLeft : window.pageXOffset
      var y = document.all ? document.body.scrollTop  : window.pageYOffset 
      showPage(s)  
      if (cache_anchor_check(Wiki.anchor)) window.scrollTo(x, y)
      else followAnchor(Wiki.anchor) 

    }
    else show()
    showHistory()
    // the following is not necessary for every update
    //updateAuth()
  }
  else followAnchor(Wiki.anchor)
}

function makeURI (prefix, title, ext, rev, anchor, skipEncode)
{
  var p = prefix === undefined ? Wiki.prefix : prefix
  var t = title  === undefined ? Wiki.title  : title
  var e = ext    === undefined ? Wiki.ext    : ext
  var r = rev    === undefined ? Wiki.rev    : rev
  var a = anchor === undefined ? Wiki.anchor : anchor
  var q = (r ? 'r=' + r : '') + ((r && a) ? '&' : '') + (a ? 'a=' + a : '')
  var s = p + t + (e ? '.' + e : '') + (q ? '?' + q : '')
  return (skipEncode == 1) ? s : encodeURI(s) 
}

function makeURIExt (ext)
{
  return makeURI(undefined, undefined, ext, undefined, '')
}

/* ---- showing documents -------------------------------------------------- */

function viewerHTML (txt)
{
  $('#rich-viewer').show()
  $('#rich-viewer').html(txt)
  // fetch top 10 stats for Index
  if (Wiki.title == "Index")
  {
    $.get('stat', '', function (res) { $('#stat-table').html(statTable(res)) })
  }
}

function setExternalLinks ()
{
  /*
  $('#txt-btn').   attr('href', makeURI(Wiki.viewerURI, undefined, 'txt'))
  $('#html-btn').  attr('href', makeURI(Wiki.viewerURI, undefined, 'html'))
  $('#latex-btn'). attr('href', makeURI(Wiki.viewerURI, undefined, 'tex'))
  $('#adt-btn').   attr('href', makeURI(Wiki.viewerURI, undefined, 'hs'))
  */
  $('#pdf-10in-btn').  attr('href', makeURI(undefined, undefined, 'pdf', '10in-2ma-fancy-toc-yahei-10pt-2ll-2pp', ''))
  $('#pdf-9in-btn').   attr('href', makeURI(undefined, undefined, 'pdf', '9in-2ma-fancy-toc-yahei-10pt-2ll-2pp', ''))
  $('#pdf-8in-btn').   attr('href', makeURI(undefined, undefined, 'pdf', 'default', ''))
  $('#pdf-6in-btn').   attr('href', makeURI(undefined, undefined, 'pdf', '6in-1ma-plain-notoc-yahei-10pt-2ll-2pp', ''))
  $('#pdf-5in-btn').   attr('href', makeURI(undefined, undefined, 'pdf', '5in-1ma-plain-notoc-yahei-9pt-0ll-1pp', ''))
  $('#pdf-psp-btn').   attr('href', makeURI(undefined, undefined, 'pdf', 'psp-1ma-plain-notoc-yahei-9pt-0ll-1pp', ''))
  $('#pdf-iliad-btn'). attr('href', makeURI(undefined, undefined, 'zip', 'default', ''))
  $('#epub-btn').      attr('href', makeURI(undefined, undefined, 'epub', 'default', ''))
  $('#custom-btn').    attr('href', makeURI(undefined, undefined, readCookie("format").indexOf("epub") >= 0 ? 'epub' : 'pdf', readCookie("format"), ''))

  //$('#print-btn'). attr('href', makeURIExt('html'))
  $('#src-btn').   attr('href', makeURIExt('txt'))
  $('#all-src-btn').   attr('href', makeURIExt('all'))
}

function showPage (res)
{
        viewerHTML(res)
        $('#history-btn').removeClass('disabled')
        panelClose($('#edit-btn'), $('#editor'))
        processLinks()
        processImages()
        setExternalLinks()
}
 
function show ()
{
  $.get(
      makeURIExt(Wiki.ext)
    , ''

    // Showing existing document:
    , function (res)
      {
        showPage(res)
        cache_current(Wiki.path, $('#rich-viewer').html())
        followAnchor(Wiki.anchor)
      }
    , ''

    // `Showing' non-existing document:
    , function (res)
      {
        if (res.status == 404)
        {
           $('#revision').html('<i>版本暂缺</i>')
           viewerHTML('<div style="margin-top: 3em; text-align: center;">请从工具栏选择<span style="color:#bb4477;">编辑</span>来创建新文档：<strong style="color:#330055;">' + Wiki.title + '</strong></div>')
           $('#history-btn').addClass('disabled')
           panelClose($('#history-btn'), $('#history'))
           //showEditor() //todo
        }
        else
        {
           $('#revision').html('')
           viewerHTML('读取错误：<span>' + res.responseText + '</span>')
           $('#history-btn').addClass('disabled')
           panelClose($('#history-btn'), $('#history'))
           $('#edit-btn').addClass('disabled')
           panelClose($('#edit-btn'), $('#editor'))
        }
      }
  )
}

function processLinks ()
{
  $('.Reference').address()
  /*
  $(".Reference").address(
    function ()
    {
      var href = this.getAttribute("href")
      var url = ""
      if (jQuery.browser.msie && href.indexOf(Wiki.url) == 0)
      {
          url = Wiki.url
          href = href.substr(url.length)
      }
      if (!href.match(/:/))
        if (!href.match(/\./))
          this.setAttribute("href", url + '#' + href)
        else
          this.setAttribute("href", url + "../" + Wiki.prefix + href)
    }
  )
*/
  $(".Internal").address(
    function ()
    {
      var href = $(this).attr("href")
      var url = ''
      if (jQuery.browser.msie && href.indexOf(Wiki.url) == 0)
      {
          url = Wiki.url
          href = href.substr(url.length)
      }
      //this.setAttribute('href', makeURI(Wiki.viewerURI, undefined, undefined, undefined, href.substring(1), 1))
      href = makeURI(Wiki.viewerURI, undefined, undefined, undefined, href.substring(1), 1)
      return href
    }
  )
}

function processImages ()
{
  $("img").each(
    function ()
    {
      var src = this.getAttribute('src')
      if (!src.match(/:/) && !src.match(/^\../))
        this.setAttribute('src', src.replace(/^/, Wiki.prefix))
    }
  )
}

function followAnchor (ref)
{
  var target;
  if (!ref) target = $('#main')[0]
  else target = $('#' + ref)[0]
  //alert("follow anchor " + ref + "," + target)
  if (target != undefined) target.scrollIntoView()
  cache_anchor_set(ref)
  // setTimeout(
    // function ()
    // {
      // focusElement(target.childeNodes[0])
    // }, 0)
}

// function focusElement (target)
// {
  // alert(target)
  // var div = document.createElement('div')
  // document.body.appendChild(div)
  // var bcr = target.getBoundingClientRect()
  // div.style.left   = bcr.left
  // div.style.top    = bcr.top
  // div.style.width  = target.clientWidth
  // div.style.height = target.clientHeight
  // $(div).addClass('find')
  // $(div).fadeOut('slow')
// }

/* ---- authentication bar ------------------------------------------------- */

function login ()
{
  if ($('#login-btn').hasClass('disabled'))
    return;
  $('#login-status').html('&nbsp;')
  $.post(
    Wiki.loginURI
  , { username : $('#username').val()
    , password : $('#password').val()
    } 
  , function ()
    {
      $('#login-status').removeClass('error')
      $('#login-status').html('登录成功')
      panelClose($('#auth-btn'), $('#auth'))
      updateAuth()
    }
  , ''
  , function (e)
    {
      $('#login-status').addClass('error')
      $('#login-status').html('登录失败: <span>' + e.responseText + '</span>')
    }
  )
}

function logout ()
{
  if ($('#logout-btn').hasClass('disabled'))
    return;
  $('#login-status').html('&nbsp;')

  $.post(
    Wiki.logoutURI
  , function ()
    {
      $('#login-status').removeClass('error')
      $('#login-status').html('成功退出登录')
      panelClose($('#auth-btn'), $('#auth'))
      // $('#auth').fadeOut()
      updateAuth()
    }
  )
}

function userURL (user)
{
  return '<a href="#/' + user + '">' + user + '</a>'
}

function updateAuth ()
{
  $.get(
      Wiki.loginfoURI
    , ''
    , function (res)
      {
        var m = res.match(/username=(.*?\n)/)
        Wiki.user = (m && m[1]) || ''
        $('#user').html(userURL(Wiki.user))
        var bla = $('#user-ui').val(Wiki.user)
        fieldUpdate.call(bla)
      }
    , ''
    , function (res)
      {
        Wiki.user = ''
        if (res.status == 401 || res.status == 403)
        {
          $('#user').html('<i>请先登录</i>')
          fieldUpdate.call($('#user-ui').val(''))
        }
        else
        {
          $('#user').html('验证错误：<span>' + res.responseText + '</span>')
        }
      }
  )
}

function signup ()
{
  if ($('#signup-btn').hasClass('disabled'))
    return;

  $('#signup-status').html('&nbsp;')
  $.post(
    Wiki.signupURI
  , { username : $('#su-username').val()
    , password : $('#su-password').val()
    , email    : $('#su-email').val()
    } 
  , function ()
    {
      $('#signup-status').removeClass('error')
      $('#signup-status').html('注册成功')
      panelClose($('#signup-btn'), $('#signup'))
    }
  , ''
  , function (e)
    {
      $('#signup-status').addClass('error')
      $('#signup-status').html('注册失败: <span>' + e.responseText + '</span>')
    }
  )
}

/* ---- document history --------------------------------------------------- */

function showWhatsnew ()
{
  // Refuse history updates when panel is closed.
  if (!$('#history').hasClass('open'))
    return
  $('#history-btn').removeClass('open')
  $('#whatsnew-btn').addClass('open')
  $('#history-status').html('&nbsp;')
  $.get('whatsnew', '',
    function (res)
    {
      $('#history-results').html(historyTable(res.asHTML().split("\n\n"), 1, 0, 1))
      $('#history-status').removeClass('error')
    },
    '',
    function (e)
    {
      $('#history-results').html('')
      $('#history-status').addClass('error')
      $('#history-status').html('无法获取最新动态：<span>' + e.responseText + '</span>')
    }
  )
}

function showCustomizer ()
{
  if ($('#format-btn').hasClass('open'))
  {
    if ($('#pdf-custom-btn').hasClass('open')) 
    { 
      $('#customizer').show()
    }
  }
  else
  {
    $('#customizer').hide()
  }
}

function readCustomSetting ()
{
  var defaultformat = "8in-2ma-fancy-toc-yahei-10pt-2ll-2pp"
  var format = readCookie("format")
  if (format == null) 
  {
    format = defaultformat
    createCookie("format", format, 365)
  }
  var a = format.split("-")
  if (a.length != 8) a = defaultformat.split("-")
  $('#pagesize').val(a[0])
  $('#margin').val(a[1])
  $('#header').val(a[2])
  $('#toc').val(a[3])
  $('#fontname').val(a[4])
  $('#fontsize').val(a[5])
  $('#linespread').val(a[6])
  $('#parskip').val(a[7])
}

function saveCustomSetting ()
{
  var format = 
    [$('#pagesize').val(),
     $('#margin').val(),
     $('#header').val(),
     $('#toc').val(),
     $('#fontname').val(),
     $('#fontsize').val(),
     $('#linespread').val(),
     $('#parskip').val() ].join('-')
  createCookie('format', format, 365)
  $('#custom-btn'). attr('href', makeURI(undefined, undefined, format.indexOf('epub') >= 0 ? 'epub' : 'pdf', format, ''))
}

function showHistory ()
{
  // Refuse history updates when panel is closed.
  if (!$('#history').hasClass('open') || !$('#history-btn').hasClass('open'))
    return
  $('#whatsnew-btn').removeClass('open')
  $('#history-btn').addClass('open')
  $('#history-status').html('&nbsp;')
  $.get(makeURIExt('his'), '',
    function (res)
    {
      $('#history-results').html(historyTable(res.asHTML().split("\n\n")))
      $('#history-status').removeClass('error')
    },
    '',
    function (e)
    {
      $('#history-results').html('')
      $('#history-status').addClass('error')
      $('#history-status').html('无法获取历史记录: <span>' + e.responseText + '</span>')
    }
  )
}

function toStr(i)
{
  var s = i.toString();
  return (s.length == 1 ? "0" + s : s);
}

function shortName(s, n)
{
  var u = ""
  for (var i = 0; i < s.length; i++)
  {
    var c = s.charCodeAt(i)
    n = n - (c > 255 ? 2 : 1)
    if (n < 0) { u = u + '...'; break }
    u = u + s.charAt(i)
  }
  return u;
}

function toLocalTime (s)
{
   var d = new Date(Date.parse(s))
   s = toStr(d.getMonth() + 1) + "/" + toStr(d.getDate()) + "/" +
       d.getFullYear().toString().substring(2) + " " +
       toStr(d.getHours()) + ":" + toStr(d.getMinutes())
   return s
}

function statTable (res)
{
  var stat = res.asHTML().split('\n\n')
  function item(i)
  {
    uri = makeURI(Wiki.viewerURI, i)
    return '<a title="' + i + '" href="#' + uri + '">' + shortName(i, 16) + '</a>'
  }
  function col(c)
  {
    return '<ul><li>' + c.split('\n').map(item).join('</li><li>') + '</li></ul>'
  }
  return [ 
    , '<center><table><tr>'
    , '<th>本周点击排行</th>'
    , '<th>本周下载排行</th>'
    , '<th>本月点击排行</th>'
    , '<th>本月下载排行</th></tr>' 
    , '<tr><td valign="top">'
    , stat.map(col).join('</td><td valign="top">'),
    , '</td></tr></table></center>' ].join('')
}

function historyTable (res, showName, startIndex, noCurrent)
{
  function row (c, i)
  {
    if (c == "") return "";
    var modified    = c.match( /(^|[\n])date=([^\n]*)/        )[2]
    var author      = c.match( /(^|[\n])author=([^\n]*)/      )[2]
    var description = c.match( /(^|[\n])description=(.*)/     )[2]
    var revid       = c.match( /(^|[\n])id=([^\n]*)/          )[2]
    var name        = c.match( /(^|[\n])name=(.*)/            )[2]
    description = description == "" ? "(comment missing)" : description; 
    // Side note.
    var klass = ""
    if (!noCurrent && ((i == 0 && !Wiki.rev) || revid == Wiki.rev)) klass = "class=current"

    return [
      , '<tr $klass>'
      , '<td style="width:8em">$modified</td>'
      , '<td>$author</td>'
      , '<td><a href="#$uri">$description</a></td>'
      , '</tr>'
      ].join('').interpolate({
          'uri'         : makeURI(Wiki.viewerURI, showName == 1 ? name : undefined, undefined, revid)
        , 'klass'       : klass
        , 'modified'    : toLocalTime(modified)
        , 'author'      : userURL(author)
        , 'description' : showName ? name + ": " + description : description
      })
  }

  function col (c)
  {
    return '<td>' + c + '</td>'
  }
  if (!startIndex) startIndex = 0
  var prevClass = startIndex ? '' : 'disabled'
  var nextClass = (startIndex + Wiki.historyPageSize >= res.length) ? 'disabled' : ''
  $('#history-status').html('<a id="history-prev-btn" class="' + prevClass + 
      '">上一页</a>&nbsp;<a id="history-next-btn" class="' + nextClass + '">下一页</a>')
  if (prevClass == '') $('#history-prev-btn').click(
      function () { $('#history-results').html(historyTable(res, showName, startIndex - Wiki.historyPageSize, noCurrent)) } )
  if (nextClass == '') $('#history-next-btn').click(
      function () { $('#history-results').html(historyTable(res, showName, startIndex + Wiki.historyPageSize, noCurrent)) } )
  return '' + 
    '<table cellpadding="0" cellspacing="0">' +
    /*
    '<tr><th id="modified">修改时间</th>' +
    '<th id="author">修改人</th>' +
    '<th id="changename">修改说明</th>' +
    '</tr>' +
    */
    range(res, startIndex, Wiki.historyPageSize).map(row).join('')
    + '</tbody></table>'
}

function range (arr, i, len)
{
   if (arr.length < i + len) len = arr.length - i
   if (len < 0) len = 0
   var res = new Array()
   for (var j = 0; j < len; j++) res[j] = arr[i + j]
   return res
}



/* ---- document editor ---------------------------------------------------- */

function showEditor ()
{
  $('#rename').hide()
  $('#editField').val('')
  $('#save-btn').click(save)

  $.get(makeURIExt('txt'), '',

    // Editing an existing document:
    function (res)
    {
      $('#editField').val(res)
    })
}
/*
'',

    // `Editing' a new document:
    function (res)
    {
      $('#editField').val('')
    }
  )
}*/


function save (obj, title)
{
  if (!Wiki.user)
    return;
  $('#edit-status').html('&nbsp;')

  $.put(
    makeURI(undefined, title, 'txt', $('#change.full').val())
  , $('#editField').val()
  , function ()
    {
      $('#edit-status').removeClass('error')
      $('#edit-status').html('存档成功')
      panelClose($('#edit-btn'), $('#editor'))
      Wiki.rev = '' // clear rev since save always updates latest rev
      if (title != undefined && title != Wiki.title) $.address.value("/" + title) //document.location.hash = title 
      else $.address.value("/" + Wiki.title) //document.location.hash = Wiki.title 
      show()
      showHistory()
    }
  , ''
  , function (e)
    {
      $('#edit-status').addClass('error')
      $('#edit-status').html('存档失败: <span>' + e.responseText + '</span>')
    }
  )
}

function preview ()
{
  $('#edit-status').html('&nbsp;')
  $.put(
    Wiki.previewURI + makeURI() 
  , $('#editField').val()
  , function (res)
    {
      viewerHTML(res)
      processLinks()
      processImages()
      $('#edit-status').removeClass('error')
      $('#edit-status').html('预览成功')
    }
  , ''
  , function (e)
    {
      $('#edit-status').addClass('error')
      $('#edit-status').html('预览失败: <span>' + e.responseText + '</span>')
    }
  )
}

function rename ()
{
  $._delete(
    makeURI(undefined, undefined, '', $('#change.full').val())
  , $('#rename').val()
  , function (res)
    {
      $('#edit-status').removeClass('error')
      $('#edit-status').html('更名成功')
      //document.location.hash = $('#rename').val()
    }
  )
}

function _delete ()
{
  $._delete(
    makeURI(undefined, undefined, '', $('#change.full').val())
  , ''
  , function (res)
    {
      $('#edit-status').removeClass('error')
      $('#edit-status').html('删除成功')
      //document.location.hash = ''
    }
  )
}

/* ---- search bar --------------------------------------------------------- */

function search ()
{
  $('#search').show()
  $('#search-status').removeClass('error')
  $('#search-status').html('搜索中...')
  var name = $('#search-terms').val()
  $.post(
    Wiki.searchURI
  , { keywords   : name
  /*, wholewords : 'False'
    , matchall   : 'False'
    , ignorecase : $('#search-case:checked').length == 0 ? 'True' : 'False'*/
    }
  , function (res)
    {
      var rs = Wiki.search.results = res.asHTML().split("\n\n")
      Wiki.search.index = 0

      if (!rs || rs.length == 0 || (rs.length == 1 && !rs[0])) {
        $('#search-status').addClass('error')
        $('#search-status').html('搜索无结果')
        searchPrevReset()
        searchNextReset()
        $('#search-results').html('')
      } else {
        $('#search-status').removeClass('error')
        $('#search-status').html('搜索成功 (' + rs.length + ' 条)')
        $('#search-results').html(searchTable())
      }
      //window.location.hash = name 
      $.address.value("/" + name)
    }
  , ''
  , function (e)
    {
      $('#search-status').addClass('error')
      $('#search-status').html('搜索失败: <span>' + e.responseText + '</span>')
    }
  )

}

function searchPrevReset ()
{
  $('#search-prev-btn').addClass('disabled')
  $('#search-prev-btn').html('前次搜索结果')
}

function searchNextReset ()
{
  $('#search-next-btn').addClass('disabled')
  $('#search-next-btn').html('更多搜索结果')
}

function searchNext ()
{
  if ($('#search-next-btn').hasClass('disabled'))
    return;

  Wiki.search.index += Wiki.search.max
  $('#search-results').html(searchTable())
}

function searchPrev ()
{
  if ($('#search-prev-btn').hasClass('disabled'))
    return;

  Wiki.search.index -= Wiki.search.max
  $('#search-results').html(searchTable())
}

function searchTable ()
{
  function row (c, i)
  {
    var resource   = c.match( /(^|[\n])resource=(.*)$/   )[2]

    return [ '<li><a href="#$uri">$resource</a></li>' ].join('').interpolate({
          'uri'        : makeURI(Wiki.viewerURI, resource, undefined, '')
        , 'resource'   : resource
      })
  }

  var rs      = Wiki.search.results
      ix      = Wiki.search.index
      max     = Wiki.search.max
      prevIx  = Math.max(0,             ix - max) 
      prevMax = Math.max(0,             ix) 
      nextIx  = Math.min(rs.length - 1, ix + max)
      nextMax = Math.min(rs.length - 1, ix + max + max)

  if (prevMax > 0) {
    $('#search-prev-btn').removeClass('disabled')
    $('#search-prev-btn').html('前次 <span>(' + prevIx + '-' + prevMax + ')</span>')
  } else
    searchPrevReset()

  if (nextIx < rs.length - 1) {
    $('#search-next-btn').removeClass('disabled')
    $('#search-next-btn').html('更多 <span>(' + nextIx + '-' + nextMax + ')</span>')
  } else
    searchNextReset()

  return "<ul>" + rs.slice(ix, ix + max).map(row).join('') + "</ul>"
}

function is_space(s)
{
    for (var i = 0; i < s.length; i++)
    {
        var c = s.substring(i, i+1);
        if (!(c == "　" || c == " "))
          return 0;
    }
    return 1;
}

function insert_break()
{
    var box = document.getElementById("editField");    
    var lines = box.value.split('\n');
    var i, s = "";
    var inpara = 1;

    for (i = 0; i < lines.length; i++)
    {
    	var t = lines[i];
        var len = t.length;
        if (len > 0 && t.charAt(len - 1) == '\r') t = t.substring(0, len - 1);
        if (is_space(t) == 1)
        {
            inpara = 0;
        }
        else
        {
            if (len >= 2)
            {
                if (t.substring(0, 1) == "　") inpara = 0;
                if (t.substring(0, 1) == " ") inpara = 0;
            }
            if (inpara == 0) s = s + "\n";
            inpara = 1;
            if (s == "") s = s + t;
            else s = s + "\n" + t;
        }
    }
    box.value = s;
    box.focus();
}

function remove_space()
{
    var box = document.getElementById("editField");    
    var lines = box.value.split('\n');
    var i, s;
    s = "";
    for (i = 0; i < lines.length; i++)
    {
    	var t = lines[i];
        var len = t.length;
        if (len > 0 && t.charAt(len - 1) == '\r') t = t.substring(0, len - 1);
        var j = 0;
        while (j < len && j < 2) 
        {
            if (t.charAt(j) != ' ') break;
            j++;
        }
        if (s.length > 0) s = s + "\n" + t.substring(j, t.length);
        else s = t.substring(j, t.length);
    }
    box.value = s;
    box.focus();
}

/* try to implement a short period of history to avoid loading pages when
 * pressing back and forward buttons
 */
var cache_store = new Array(10);
var cache_pos = 0;

/* store current page data in cache by forwarding to the next position.
 */
function cache_current(url, page)
{
  var pos = cache_pos + 1
  if (pos > cache_store.length - 1) pos = 0
  cache_store[pos] = { id : url, anchor : "", data : page }
  cache_pos = pos
  pos = cache_pos + 1
  if (pos > cache_store.length - 1) pos = 0
  cache_store[pos] = null
}

/* go back a page, returns the page data if its available
 */
function cache_backward()
{
  var pos = cache_pos - 1
  if (pos < 0) pos = cache_store.length - 1
  if (!cache_store[pos]) return ""
  cache_pos = pos
  return cache_store[pos].data
}

/* go forward a page, returns the page data if its available
 */
function cache_forward()
{
  var pos = cache_pos + 1
  if (pos > cache_store.length - 1) pos = 0
  if (!cache_store[pos]) return ""
  cache_pos = pos
  return cache_store[pos].data
}

/* set the anchor in cache
 */
function cache_anchor_set(anchor)
{
  if (cache_store[cache_pos])
    cache_store[cache_pos].anchor = anchor
}

/* check if the given anchor matches what's in the cache
 */
function cache_anchor_check(anchor)
{
  return cache_store[cache_pos] && cache_store[cache_pos].anchor == anchor
}

/* guess if the new url is from pressing back or forward button.
 * returns -1 if it's backword, 1 if it's forward, and 0 otheriwse.
 */
function cache_guess(url)
{
  var pos = cache_pos - 1
  if (pos < 0) pos = cache_store.length - 1
  if (cache_store[pos] && cache_store[pos].id == url) return -1
  pos = cache_pos + 1
  if (pos > cache_store.length - 1) pos = 0
  if (cache_store[pos] && cache_store[pos].id == url) return 1
  return 0
}

