
config.messages.loginToEdit = 'You must be logged in to make changes. Click OK to log in now.';
config.messages.errorDeleting = 'There was an error deleting this tiddler. Review your Zope error log for details.';
config.messages.errorSaving = 'There was an error saving this tiddler. Review your Zope error log for details. If you navigate away from this page now, you will lose your changes.';
config.messages.revisionsButtonLabel = 'revisions';
config.messages.revisionsTooltip = 'View an older revision of this tiddler.';
config.messages.viewRevisionTooltip = 'View this revision.';
config.messages.rssLink = 'Available in RSS';
config.messages.loginLinkLabel = 'log in';
config.messages.loginLinkPrompt = 'Log in.';
config.messages.logoutLinkLabel = 'log out';
config.messages.logoutLinkPrompt = 'Log out.';
config.messages.exportLinkLabel = 'export';
config.messages.exportLinkPrompt = 'Export to a TiddlyWiki file.';
config.messages.importLinkLabel = 'import';
config.messages.importLinkPrompt = 'Import a TiddlyWiki file.';

config.shadowTiddlers.AdvancedOptions = '<<option chkOpenInNewWindow>> OpenLinksInNewWindow\n<<option chkToggleLinks>> Clicking on links to tiddlers that are already open causes them to close\n^^(override with Control or other modifier key)^^';
config.shadowTiddlers.OptionsPanel = 'These options are saved in your browser\n\n<<option chkRegExpSearch>> RegExpSearch\n<<option chkCaseSensitiveSearch>> CaseSensitiveSearch\n<<option chkAnimate>> EnableAnimations\n\nSee AdvancedOptions';
config.shadowTiddlers.SideBarOptions = '<<search>><<closeAll>><<permaview>><<slider chkSliderOptionsPanel OptionsPanel options "Change advanced options">><<exportLink>><<importLink>><<login>>';

config.animFast = 0.20;

ie = navigator.appVersion.indexOf('MSIE') > -1;
ieurl = ie ? 'ie=1&' : '';

config.macros.login = {
  label: config.messages.loginLinkLabel,
  prompt: config.messages.loginLinkLabel,
  handler: function(place) { if(!loggedIn) createTiddlyButton(place,this.label,this.prompt,function(){location.href='?action=login&' + ieurl + 'redirect_to=./'}) }
};

config.macros.logout = {
  label: config.messages.logoutLinkLabel,
  prompt: config.messages.logoutLinkLabel,
  handler: function(place) { if(loggedIn) createTiddlyButton(place,this.label,this.prompt,function(){location.href='?action=logout&' + ieurl + 'redirect_to=./'}) }
};

config.macros.AddUserForm = {
handler: function(place) {
 var form = createTiddlyElement(place,'form');
 form.setAttribute('action', 'add_user');
 form.appendChild(formField('user_name', 'User Name'));
 form.appendChild(formField('password', 'Password', true));
 form.appendChild(formField('password_confirm', 'Password Again', true));
 var return_to = document.createElement('input');
 return_to.setAttribute('type', 'hidden');
 return_to.setAttribute('name', 'return_to');
 return_to.setAttribute('value', location.href);
 form.appendChild(return_to);
 var p = document.createElement('p');
 p.innerHTML = '<input type="submit" value="Create User"/>';
 form.appendChild(p);
 }
};

function formField(name, label, password) {
 var p = document.createElement('p');
 p.innerHTML = '<label for="' + name + '">' + label + ':</label><br/><input ' + (password ? 'type="password" ' : '') + 'id="' + name +'" name="' + name + '"/>';
 return p;
};




config.macros.exportLink = {
  label: config.messages.exportLinkLabel,
  prompt: config.messages.exportLinkPrompt,
  handler: function(place) { createTiddlyButton(place,this.label,this.prompt,function(){location.href='?action=export'}) }
};

config.macros.importLink = {
  label: config.messages.importLinkLabel,
  prompt: config.messages.importLinkPrompt,
  handler: function(place) { if(loggedIn) createTiddlyButton(place,this.label,this.prompt,function(){location.href='?action=import'}) }
};

config.macros.ziddlySnapshot = {
  handler: function(place) { createTiddlyElement(place,'span',null,null,version.extensions.ziddly) }
};

function ziddlyStatus(message) {
  if(!window.statusElm) { // create the "status" element
    statusElm = document.createElement('div');
    statusElm.id = 'savingMessage';
    statusElm.style.display = 'none';
    document.body.appendChild(statusElm);
  }
  if(message) {
    statusElm.innerHTML = message;
    statusElm.style.display = 'block';
  } else {
    statusElm.style.display = 'none';
  }
};

TiddlyWiki.prototype._removeTiddler = TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler = function(title) {
  ziddlyStatus('deleting...');
  var callback = function(r){
    ziddlyStatus(false);
    if(r!='success') alert(config.messages.errorDeleting);
  };
  ajax.post('./', callback, 'action=delete&id=' + title + '&' + noCache());
  return this._removeTiddler(title);
};

TiddlyWiki.prototype._saveTiddler = TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags) {
  ziddlyStatus('saving...');
  var callback = function(r){
    ziddlyStatus(false);
    if(r != 'success') alert(config.messages.errorSaving);
  };
  ajax.post('./', callback, 'action=save&id=' + title + '&title=' + encodeURIComponent(newTitle) + '&body=' + encodeURIComponent(newBody) + '&tags=' + encodeURIComponent(tags) + '&path=' + encodeURIComponent(ziddlyPath) + '&' + noCache());
  return this._saveTiddler(title,newTitle,newBody,username,modified,tags);
};

function noCache() {return new String((new Date()).getTime())};

function ziddlyGetTiddler(title,revision) {
  revision = revision ? '&revision=' + revision : '';
  var encoded = ajax.gets('?action=get&id=' + title + revision + '&' + noCache());
  if(encoded == '-') {
    return null;
  } else {
    var parts = encoded.split('\n');
    var tiddler = new Tiddler();
    tiddler.set(parts[0], parts[1].replace(regexpBackSlashEn, '\n').replace(/&lt;/g, '<').replace(/&gt;/g, '>'), parts[2], Date.convertFromYYYYMMDDHHMM(parts[3]), parts[4]);
    return tiddler;
  }
};

function ziddlyCreateTiddlerToolbar(title,editor) {
  _createTiddlerToolbar(title,editor);
  var theToolbar = document.getElementById("toolbar" + title);
  if(!editor) {
    insertSpacer(theToolbar);
    createTiddlyButton(theToolbar,config.messages.revisionsButtonLabel,config.messages.revisionsTooltip,onClickToolbarRevisions);
  }
};
_createTiddlerToolbar = createTiddlerToolbar;
createTiddlerToolbar = ziddlyCreateTiddlerToolbar;

function displayTiddlerRevision(title, revision, src) {
  ziddlyStatus('loading...');
  store.tiddlers[title] = ziddlyGetTiddler(title, revision);
  var tiddler = document.getElementById("tiddler" + title);
  tiddler.parentNode.removeChild(tiddler);
  displayTiddler(document.getElementById('header'), title, 0, null, null, null, false);
  store.tiddlers[title].revisionKey = revision;
  ziddlyStatus(false);
};

function onClickToolbarRevisions(e) {
  if(!e) var e = window.event;
  clearMessage();
  var theTarget = resolveTarget(e);
  var target = this;
  if(this.parentNode.id) {
    var title = this.parentNode.id.substr(7);
    var callback = function(r) {
      var popup = createTiddlerPopup(target);
      var revisions = r.split('\n');
      for(var i=0; i<revisions.length; i++) {
        var parts = revisions[i].split(' ');
        var modified = Date.convertFromYYYYMMDDHHMM(parts[0]);
        var key = parts[1];
        var button = createTiddlyButton(popup, modified.toLocaleString(), config.messages.viewRevisionTooltip, function(){displayTiddlerRevision(this.getAttribute('tiddlerTitle'), this.getAttribute('revisionKey'), this)}, 'tiddlyLinkExisting tiddlyLink');
        button.setAttribute('tiddlerTitle', title);
        button.setAttribute('revisionKey', key);
        var tiddler = store.tiddlers[title];
        if(tiddler.revisionKey == key || (!tiddler.revisionKey && i==0))
          button.className = 'revisionCurrent';
      }
    };
    ajax.get('?action=get_revisions&id=' + title + '&' + noCache(), callback);
    e.cancelBubble = true;
    if (e.stopPropagation) e.stopPropagation();
    return(false);
  }
};

function initZiddly() {
  // run the early skin init method (if it exists)
  if(window.skinInitEarly) window.skinInitEarly();

  _main();

  var sidebar = document.getElementById('sidebar');

  // add the XML and YAML icons
  var xmlIcon = document.createElement('div');
  xmlIcon.id = 'xmlIcon';
  xmlIcon.innerHTML = 'alternate formats:<br/><a href="?format=xml" title="RSS"><img src="../ZiddlyWiki/images/xml.gif"/></a> <a href="?format=yaml" title="YAML"><img src="../ZiddlyWiki/images/yaml.gif"/></a>';
  sidebar.appendChild(xmlIcon);

  // add the ZW badge graphic
  var zwBadge = document.createElement('div');
  zwBadge.id = 'zwBadge';
  zwBadge.innerHTML = '<a href="http://ziddlywiki.com/" title="powered by ZiddlyWiki"><img src="ZiddlyWiki/images/badge.png" alt="powered by ZiddlyWiki"/></a>';
  sidebar.appendChild(zwBadge);

  // run the skin init method (if it exists)
  if(window.skinInit) window.skinInit();
};
_main = main;
main = initZiddly;

function ziddlyOnClickToolbarDelete(e) {
  if(confirm('Are you sure you want to delete this tiddler?'))
    _onClickToolbarDelete.call(this, e);
};
_onClickToolbarDelete = onClickToolbarDelete;
onClickToolbarDelete = ziddlyOnClickToolbarDelete;

function permaviewHash() {
  var tiddlerDisplay = document.getElementById("tiddlerDisplay");
  var links = [];
  for(var t=0; t<tiddlerDisplay.childNodes.length; t++) {
    var tiddlerName = tiddlerDisplay.childNodes[t].id.substr(7);
    links.push(String.encodeTiddlyLink(tiddlerName));
  }
  return encodeURIComponent(links.join(" "));
}

function askToLogin() {
 if(confirm(config.messages.loginToEdit)) setTimeout("location.replace('?action=login&' + ieurl + 'redirect_to=./%23' + permaviewHash());", 10);
};

_onClickToolbarEdit = onClickToolbarEdit;
onClickToolbarEdit = function(e) { loggedIn || anonEdit ? _onClickToolbarEdit.call(this, e) : askToLogin() };
_onDblClickTiddler = onDblClickTiddler;
onDblClickTiddler = function(e) { loggedIn || anonEdit ? _onDblClickTiddler.call(this, e) : askToLogin() };

// There's no doubt a better solution to the popup position problem that ZW experiences;
// until I find it, this will do the trick.
/*
function findPosX(obj) {
  if(ie) return obj.offsetLeft;
  if(obj.className == 'button') return obj.offsetLeft;
  var curleft = 0;
  while (obj.offsetParent) {
    curleft += obj.offsetLeft;
    obj = obj.offsetParent;
  }
  return curleft;
}
function findPosY(obj) {
  if(ie) return obj.offsetTop;
  var curtop = 0;
  while (obj.offsetParent) {
    curtop += obj.offsetTop;
    obj = obj.offsetParent;
  }
  return curtop;
}
*/

function checkUnsavedChanges() {};