// easyedit form logic...

var UPLOADSPATH = './data', ENABLEDCOLOR = '#fff', DISABLEDCOLOR = '#666';

var form, pass_changed = false, file_changed = false, thmb_changed = false, page, pindex, section, sindex, upload, uindex, utype, nonce;

var QUOTA = 100 * 1024 * 1024, usage = 0;

var CHGD_STTL = 0x001;
var CHGD_BLRB = 0x002;
var CHGD_POSN = 0x004;

var CHGD_UTTL = 0x008;
var CHGD_CBCP = 0x010;
var CHGD_CBTH = 0x020;
var CHGD_CBIC = 0x040;
var CHGD_UURL = 0x080;
var CHGD_FILE = 0x100;
var CHGD_THMB = 0x200;

var schanges = 0x0, uchanges = 0x0;

// authentication

function changed_pass() { // activate form

 form.page.disabled =
 form.sect.disabled =
 form.sttl.disabled =
 form.blrb.disabled =
 form.posn.disabled =

 form.list.disabled =
 form.uttl.disabled =
 form.cbcp.disabled =
 form.cbth.disabled =
 form.cbic.disabled =
 form.uurl.disabled =
 form.file.disabled =
 form.thmb.disabled =

 form.savs.disabled = // button
 form.delu.disabled = // button
 form.savu.disabled = // button
 //form.upld.disabled = // button
 form.snap.disabled = // button

  false;

 static_page();
}

// content editor

function static_page() {
 form.sect.disabled =
 form.sttl.disabled =
 form.blrb.disabled =
 form.posn.disabled =
  !!data.pages[form.page.selectedIndex].is_static;
}


function changed_page() { // populate sections
 //page = data.pages[form.page.options[form.page.selectedIndex].value];
 page = data.pages[form.page.selectedIndex];

 static_page();

 if (page.is_test)
  document.getElementById('pageid').innerHTML =
   '<a href="javascript:window.open(\'' + page.path + '\', \'_blank\');void(0);" title="(opens in new window)">Test Page</a>';
 else
  document.getElementById('pageid').innerHTML = 'ID = ##' + page.id + '##';
 var sections = page.sections;
 form.sect.options.length = 0;
 for (var i = 0, n = sections.length; i < n; i++) { //if (!sections[i].title) alert(i)
  form.sect.add(new Option(sections[i].title, i, false, false), undefined);
 }
 form.sect.selectedIndex = n > 1;
 changed_sect();
}

function changed_sect() { // populate title/blurb/position
 sindex = form.sect.selectedIndex; // form.sect.options[form.sect.selectedIndex].value; // assuming == .value
 section = page.sections[sindex];
 var sections = page.sections;

 form.posn.options.length = 0;//(alert([sindex, form.sect.options[sindex].value]))
 form.posn.add(new Option('First (always displayed first)', '0', false, false), undefined);
 for (var i = 1, n = sections.length; i < n; i++)
  form.posn.add(new Option('After "' + sections[i].title + '"', i, false, false), undefined);

 if (sindex == 0) {
  form.sttl.value = form.blrb.value = '';
  form.posn.selectedIndex = 0;
  //form.sttl.focus();
 }
 else {
  form.sttl.value = section.title;
  form.blrb.value = section.blurb;
  form.posn.add(new Option('DELETE!', n, false, false), undefined);
  var i = sindex - !!(sindex);
  form.posn.selectedIndex = i;
  //if (i) form.posn.options[i+1].disabled = true;
 }
 schanges = 0;
 set_save_section();
}

function clicked_sect_tcase() {
 //alert('clicked_sect_tcase');
 form.sttl.value = form.sttl.value.titleCase();
 changed_sect_title();
}

function changed_sect_title() { //
 //alert('changed_sect_title');
 schanges = form.sttl.value == section.title ? ~(~schanges|CHGD_STTL) : schanges|CHGD_STTL; // un:set
 set_save_section();
}

function changed_sect_blurb() {
 //alert('changed_sect_blurb');
 schanges = form.blrb.value == section.blurb ? ~(~schanges|CHGD_BLRB) : schanges|CHGD_BLRB; // un:set
 set_save_section();
}

function changed_sect_position() {
 //alert('changed_sect_position');
 var d = sindex - !!(sindex); // default
 if (form.posn.selectedIndex == sindex)
  form.posn.selectedIndex = d;
 schanges = form.posn.selectedIndex == d ? ~(~schanges|CHGD_POSN) : schanges|CHGD_POSN; // un:set
 set_save_section();
}

var BIG_BLURB = false;

function toggled_blurb_size() {
 BIG_BLURB = !BIG_BLURB;

 var e = document.getElementById('blrb_e');
 if (!e) return;
 e.style.height = BIG_BLURB ? '400px' : '96px';

 var e = document.getElementById('bb');
 if (!e) return;
 e.innerHTML = BIG_BLURB ? 'Smaller' : 'Bigger';
}

// uploads manager

function changed_upload() {
 //alert('changed_upload')

 uindex = parseInt(form.list.options[form.list.selectedIndex].value);
 upload = data.uploads[0];
 for (var i = 0, n = data.uploads.length; i < n; i++)
  if (data.uploads[i].index == uindex) { upload = data.uploads[i]; break; } // kludge

 utype  = uindex ? upload['type'] : '';

 if (upload.linkURL) changed_upload_link();

 uchanges = 0;//uchanges & (CHGD_FILE|CHGD_THMB);

 // info
 var preview = document.getElementById('preview');
 preview.onerror = function() {
  preview.width = 186, preview.height = 40; // FIXME magic nums!
  preview.src = './no_preview.png';
 };
 var s = usage;
 if (!uindex) {
  preview.width = 186, preview.height = 40; // FIXME magic nums!
  preview.src = './no_preview.png';
  s += ', NEW upload...';
 }
 else {

  if (upload.imageW && upload.imageH) {
   s += ', ' + upload.imageW + 'px x ' + upload.imageH + 'px';
  }
  else if (upload.thumbW && upload.thumbH) {
   s += ', ' + upload.thumbW + 'px x ' + upload.thumbH + 'px';
  }

  if      (upload.type == 'video' && upload.thumb) {
   preview.width = upload.thumbW, preview.height = upload.thumbH;
   preview.src = UPLOADSPATH + '/' + upload.thumb;
  }
  else if (upload.type == 'image') {
   if (upload.thumb && upload.thumbW < upload.imageW) {
    preview.width = upload.thumbW, preview.height = upload.thumbH;
    preview.src = UPLOADSPATH + '/' + upload.thumb;
   }
   else {
    preview.width = upload.imageW, preview.height = upload.imageH;
    preview.src = UPLOADSPATH + '/' + upload.file;
   }
  }
  else {
   preview.width = 186, preview.height = 40; // FIXME magic nums!
   preview.src = './no_preview.png';
  }
  if (upload.fileSize)
   s += ', ' + kilomega(upload.fileSize, 3) + 'B';
  if (upload.timestamp)
   s += ', Modified ' + upload.timestamp;
  s += ', Refs = ' + upload.refs + ', ID = ##' + upload.id + '##';
 }
 document.getElementById('upload_info').innerHTML = s;

 // seems to work - reset file inputs
 document.getElementById('file_d').innerHTML = document.getElementById('file_d').innerHTML;
 document.getElementById('thmb_d').innerHTML = document.getElementById('thmb_d').innerHTML;
 form.file.onchange = changed_local;
 form.thmb.onchange = changed_thumb;

 set_inputs();

 set_save_upload();
 set_delete_upload();
}

function set_inputs() {
 // TODO - lift this to other function - changed url + file need it

 // populate + en/disable inputs

 if      (!uindex) { //alert('new')
  if (!(uchanges & CHGD_UTTL)) form.uttl.value    = '';
  if (!(uchanges & CHGD_CBIC)) form.cbic.checked  = false;
  if (!(uchanges & CHGD_CBCP)) form.cbcp.checked  = false;
  if (!(uchanges & CHGD_CBTH)) form.cbth.checked  = false;
  if (!(uchanges & CHGD_UURL)) form.uurl.value    = '';

  form.uttl.disabled = false;
  form.cbic.disabled = false;
  form.cbcp.disabled = false;
  form.cbth.disabled = false;
  form.uurl.disabled = false;
  form.file.disabled = false;
  form.thmb.disabled = false;

  form.delu.disabled = true;
  form.savu.disabled = true;

  document.getElementById('cbic_l').style.display = 'inline';
  document.getElementById('cbcp_l').style.display = 'inline';
  document.getElementById('cbth_l').style.display = 'inline';
  document.getElementById('thmb_d').style.display = 'none';
 }
 else if (utype == 'image') { //alert('image')
  //var url_ok =
  if (!(uchanges & CHGD_UTTL)) form.uttl.value    = upload.title;
  if (!(uchanges & CHGD_CBCP)) form.cbcp.checked  = !!upload.hasCaption;
  if (!(uchanges & CHGD_CBTH)) form.cbth.checked  = !!upload.hasClickable;
  if (!(uchanges & CHGD_UURL)) form.uurl.value    = upload.linkURL || '';
  if (!(uchanges & CHGD_CBIC)) form.cbic.checked  = false;

  form.uttl.disabled = false;
  form.cbic.disabled = true;
  form.cbcp.disabled = false;
  form.cbth.disabled = false;
  form.uurl.disabled = false;
  form.file.disabled = false;
  form.thmb.disabled = true;

  form.delu.disabled = true;
  form.savu.disabled = true;

  document.getElementById('cbic_l').style.display = 'none';
  document.getElementById('cbcp_l').style.display = 'inline';
  document.getElementById('cbth_l').style.display = 'inline';
  document.getElementById('thmb_d').style.display = 'none';
 }
 else if (utype == 'video') { //alert('video')
  if (!(uchanges & CHGD_UTTL)) form.uttl.value    = upload.title;
  if (!(uchanges & CHGD_CBCP)) form.cbcp.checked  = !!upload.hasCaption;
  if (!(uchanges & CHGD_UURL)) form.uurl.value    = upload.linkURL || '';
  form.cbic.checked  = false;
  form.cbth.checked  = false;

  form.uttl.disabled = false;
  form.cbic.disabled = true;
  form.cbcp.disabled = false;
  form.cbth.disabled = true;
  form.uurl.disabled = false;
  form.file.disabled = false;
  form.thmb.disabled = false;

  form.delu.disabled = true;
  form.savu.disabled = true;

  document.getElementById('cbic_l').style.display = 'none';
  document.getElementById('cbcp_l').style.display = 'inline';
  document.getElementById('cbth_l').style.display = 'none';
  document.getElementById('thmb_d').style.display = 'inline';
 }
 else if (utype == 'audio') { //alert('audio')
  if (!(uchanges & CHGD_UTTL)) form.uttl.value    = upload.title;
  if (!(uchanges & CHGD_CBCP)) form.cbcp.checked  = !!upload.hasCaption;
  if (!(uchanges & CHGD_UURL)) form.uurl.value    = upload.linkURL || '';
  form.cbic.checked  = false;
  form.cbth.checked  = false;

  form.uttl.disabled = false;
  form.cbic.disabled = true;
  form.cbcp.disabled = false;
  form.cbth.disabled = true;
  form.uurl.disabled = false;
  form.file.disabled = false;
  form.thmb.disabled = true;

  form.delu.disabled = true;
  form.savu.disabled = true;

  document.getElementById('cbic_l').style.display = 'none';
  document.getElementById('cbcp_l').style.display = 'inline';
  document.getElementById('cbth_l').style.display = 'none';
  document.getElementById('thmb_d').style.display = 'none';
 }
 else { //alert('other')
  if (!(uchanges & CHGD_UTTL)) form.uttl.value    = upload.title;
  if (!(uchanges & CHGD_CBIC)) form.cbic.checked  = !!upload.hasIcon;
  form.cbcp.checked  = false;
  form.cbth.checked  = false;
  form.uurl.value    = '';

  form.uttl.disabled = false;
  form.cbic.disabled = false;
  form.cbcp.disabled = true;
  form.cbth.disabled = true;
  form.uurl.disabled = false; // user might change type
  form.file.disabled = false;
  form.thmb.disabled = true;

  form.delu.disabled = true;
  form.savu.disabled = true;

  document.getElementById('cbic_l').style.display = 'inline';
  document.getElementById('cbcp_l').style.display = 'none';
  document.getElementById('cbth_l').style.display = 'none';
  document.getElementById('thmb_d').style.display = 'none';
 }

 document.getElementById('chk').style.visibility = is_url_ok(form.uurl.value) ? 'visible' : 'hidden';
}

function clicked_by_az() {
 //alert('clicked_by_az');
 var n = data.uploads.shift();
 data.uploads.sort(function(a,b){
  a = String(a.title).toUpperCase(), b = String(b.title).toUpperCase();
  return a < b ? -1 : a > b ? 1 : 0;
 });
 data.uploads.unshift(n);
 form.list.options.length = 0;
 form.list.add(new Option(data.uploads[0].title, 0, 0, !uindex), undefined);
 for (var i = 1, n = data.uploads.length; i < n; i++) {
  var index = data.uploads[i].index;
  var type  = data.uploads[i].type;
  form.list.add(new Option(data.uploads[i].title +
   ' (' + type + (type == 'other' ? ' - ' + data.uploads[i].ext : '') + ')',
   index, 0, index == uindex), undefined);
 }
}

function clicked_by_type() {
 //alert('clicked_by_type');
 var n = data.uploads.shift();
 data.uploads.sort(function(a,b){
  var a0 = String(a.type).toUpperCase(),  b0 = String(b.type).toUpperCase();
  var a1 = String(a.ext || '').toUpperCase(),   b1 = String(b.ext || '').toUpperCase();
  var a2 = String(a.title).toUpperCase(), b2 = String(b.title).toUpperCase();
  return a0 < b0 ? -1 : a0 > b0 ? 1 : a1 < b1 ? -1 : a1 > b1 ? 1 : a2 < b2 ? -1 : a2 > b2 ? 1 : 0;
 });
 data.uploads.unshift(n);
 form.list.options.length = 0;
 form.list.add(new Option(data.uploads[0].title, 0, 0, !uindex), undefined);
 for (var i = 1, n = data.uploads.length; i < n; i++) {
  var index = data.uploads[i].index;
  var type  = data.uploads[i].type;
  form.list.add(new Option(data.uploads[i].title +
   ' (' + type + (type == 'other' ? ' - ' + data.uploads[i].ext : '') + ')',
   index, 0, index == uindex), undefined);
 }
}

function clicked_by_date() {
 //alert('clicked_by_date');
 var n = data.uploads.shift();
 data.uploads.sort(function(a,b){
  a = String(a.timestamp).toUpperCase(), b = String(b.timestamp).toUpperCase();
  return a > b ? -1 : a < b ? 1 : 0; // most recent first
 });
 data.uploads.unshift(n);
 form.list.options.length = 0;
 form.list.add(new Option(data.uploads[0].title, 0, 0, !uindex), undefined);
 for (var i = 1, n = data.uploads.length; i < n; i++) {
  var index = data.uploads[i].index;
  var type  = data.uploads[i].type;
  form.list.add(new Option(data.uploads[i].title +
   ' (' + type + (type == 'other' ? ' - ' + data.uploads[i].ext : '') + ')',
   index, 0, index == uindex), undefined);
 }
}

function changed_upload_title() {
 //alert('changed_upload_title');
 uchanges = form.uttl.value == upload.title ? ~(~uchanges|CHGD_UTTL) : uchanges|CHGD_UTTL; // un:set
 set_save_upload();
}

function clicked_upload_tcase() {
 //alert('clicked_upload_tcase');
 form.uttl.value = form.uttl.value.titleCase();
 changed_upload_title();
}

function changed_upload_icon() {
 //alert('changed_upload_icon');
 uchanges = form.cbic.checked == upload.hasIcon ? ~(~uchanges|CHGD_CBIC) : uchanges|CHGD_CBIC; // un:set
 set_save_upload();
}

function changed_upload_caption() {
 //alert('changed_upload_caption');
 uchanges = form.cbcp.checked == upload.hasCaption ? ~(~uchanges|CHGD_CBCP) : uchanges|CHGD_CBCP; // un:set
 set_save_upload();
}

function changed_upload_clickable() {
 //alert('changed_upload_clickable');
 uchanges = form.cbth.checked == upload.hasClickable ? ~(~uchanges|CHGD_CBTH) : uchanges|CHGD_CBTH; // un:set
 set_save_upload();
}

function get_file_type(file) {
 if (!file) return ''; // DON'T rely on input.value...
 var i = String(file).lastIndexOf('.') + 1;
 var f = file.substring(i);
 if (file.length - i < 2) // eg. '.foo'
  return 'other';
 if (f.match(/^jpeg?|jpg|png|gif$/i))
  return 'image';
 if (f.match(/^flv$/i))
  return 'video';
 if (f.match(/^mp3$/i))
  return 'audio';
 return 'other';
}

function clicked_check_url(url) {
 if (confirm(
  "Check URL (in new window)?\n\n" +
  "A 'Not Found' error means your URL is broken\n\n" +
  "TIP: It's best to paste URLs into the form which\nhave been copied from your browser's Location bar."
 ))
  window.open(form.uurl.value, '_blank');
 return false;
}

function is_url_ok(url) {

 if (url && !url.match(new RegExp('^https?://', 'i'))) url = form.uurl.value = 'http://' + url; // too helpful?

 if (!url.match(new RegExp('^https?://[-0-9a-z.]{2,}\\.[a-z]{2,4}', 'i'))) return false; // crude

 //alert(url)

 if (utype == 'image') return true;

 var type = get_file_type(url); // FIXME - messy!

 return (type == 'video' || type == 'audio');
 //if (url && !url_ok) alert('URL appears invalid, please check');

}

function changed_upload_link() {
 //alert('changed_upload_link');

 var url = form.uurl.value;


 var url_ok = is_url_ok(url)

 document.getElementById('chk').style.visibility = url_ok ? 'visible' : 'hidden';

 var type = get_file_type(url);


 if (
  url_ok && url != upload.linkURL &&
  ((!(uchanges & CHGD_FILE) && (type == 'video' || type == 'audio')) || utype == 'image')
 ) {

  // TODO Check link (ajax?)

  uchanges |= CHGD_UURL;

  if (utype != 'image')
   utype = type;


 }

 else {

  uchanges = ~(~uchanges|CHGD_UURL);

  utype = upload['type'];
 }

 set_inputs();
 set_save_upload();
}

function changed_local() {
 //alert('changed_local');

 var t = get_file_type(form.file.value);
 if (uchanges & CHGD_FILE && !t) { // we know we can access form value, and it's now empty
  uchanges = ~(~uchanges|CHGD_FILE);
  utype = upload['type'];
 }
 else { // either we have a value or we can't access form value - which may be empty :-[
  uchanges |= CHGD_FILE;
  utype = t;
 }
 set_inputs();
 set_save_upload();
}

function changed_thumb() {
 //alert('changed_thumb');
 var t = get_file_type(form.file.value);
 if (uchanges & CHGD_THMB && !t) { // see changed_local()
  uchanges = ~(~uchanges|CHGD_THMB);
  utype = upload['type'];
 }
 else {
  uchanges |= CHGD_THMB;
  utype = t;
 }
 set_save_upload();
}

String.prototype.repeat = function(count) {
 for (var s = '', i = 0; i < count; i++) s += '' + this;
 return s;
}

String.prototype.toEntities = function() {
 var s = this;
 s = s.replace(/&/g, '&amp;');
 s = s.replace(/</g, '&lt;');
 s = s.replace(/>/g, '&gt;');
 s = s.replace(/"/g, '&quot;');
 return s;
}

function clicked_dump_sm() {
 var w = window.open();
 var d = w.document;
 d.write(
  '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n',
  '<html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head>\n',
  '<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n',
  '<title>&laquo;SimpleMarkup&raquo; Dump...</title></head><body><pre>',
  String('=').repeat(80), '\n',
  'SIMPLEMARKUP FOR HOST "', window.location.host.toUpperCase(), '"\n',
  String('=').repeat(80), '\n\n',
  'Note: this is the CURRENT state of your site as of ', new Date(), '\n\n',
  'HINT: copy and paste the following into Notepad or TextEdit, edit content there, ',
  'then paste sections back into the form\'s Blurb field...\n\n'
 );
 for (var i = 0, n = data.pages.length; i < n; i++) {
  var page = data.pages[i];
  d.write('== PAGE ##', page.id, '## TITLE: ', String('=').repeat(60 - page.id.length), '\n\n');
  d.write(page.title.toEntities(), '\n\n');
  for (var j = 1, m = page.sections.length; j < m; j++) {
   var section = page.sections[j];
   d.write(
    '-- SECTION TITLE: ', String('-').repeat(62), '\n\n',
    section.title.toEntities(), '\n\n',
    '-- SECTION BLURB: ', String('-').repeat(62), '\n\n',
    section.blurb.toEntities(), '\n\n'
   );
  }
 }
 d.write('\n## REFERENCE IDs: ', String('#').repeat(62), '\n\n');
 d.write('Copy + paste them into your markup...\n\n');
 d.write('~~ PAGES (Again): ', String('~').repeat(62), '\n\n');
 for (var i = 0, n = data.pages.length; i < n; i++) {
  var page = data.pages[i];
  d.write('##', page.id, '##\t', page.title.toEntities(),'\n\n');
 }
 d.write('~~ UPLOADS: ', String('~').repeat(68), '\n\n');
 for (var i = 1, n = data.uploads.length; i < n; i++) {
  var uploads = data.uploads[i];
  d.write('##', uploads.id, '##\t', uploads.title.toEntities(),'\n\n');
 }
 if (n < 2) d.write('(No Uploads)\n\n');

 d.write('</pre></body></html>');
 d.close();
 w.focus();
}

// submission

function clicked_sect_save() {
 //alert('clicked_sect_save');
 if (!form.pass.value) {
  alert('Please enter your password!\n(Then re-submit form)'); pass_focus(); return false;
 }
 if (!form.sttl.value) {
  alert('Please ensure your section has a title!'); form.sttl.focus(); return false;
 }
 var s = '', action = '', changes = [], posn = form.posn.options[form.posn.selectedIndex].text.toLowerCase();

 if (form.sttl.value != section.title || !sindex)
  changes.push('title');
 if (form.blrb.value != section.blurb)
  changes.push('blurb');

 if (sindex == 0) {
  action = 'create_section';
  s = 'CREATE new section "' + form.sttl.value + '" ' + posn + ' ?\n';
 }
 else if (form.posn.selectedIndex == page.sections.length) {
  action = 'delete_section';
  s = 'PERMANENTLY DELETE existing section "' + section.title + '"?\nNo «EasyUploads» will be deleted\n';
 }
 else if (changes.length) {
  action = 'modify_section';
  s = 'MODIFY existing section "' + section.title + '"?\n';
  if (sindex - 1 != form.posn.selectedIndex) {
   action = 'modify_move_section';
   s += 'AND MOVE it to ' + posn + '?\n';
   changes.push('position');
  }
 }
 else if (sindex - 1 != form.posn.selectedIndex) {
  action = 'move_section';
  s = 'MOVE existing section "' + section.title + '"\nto ' + posn + '?\n';
  changes.push('position');
 }
 else { // shouldn't happen
  alert('Section not changed');
  return false;
 }

 if (confirm(s + (changes.length ? 'Changed: ' + changes.join(', ') : ''))) {
  form.a.value = action;
  submit_form();
  return true;
 }
 return false;
}

function clicked_upload_save() {
 //alert('clicked_upload_save');
 if (!form.pass.value) {
  alert('Please enter your password!\n(Then re-submit form)'); pass_focus(); return false;
 }
 // these shouldn't happen...
 if (!uchanges) {
  alert('Nothing changed.'); return false;
 }
 if (!form.uttl.value) {
  alert('Please ensure your upload has a title!'); form.uttl.focus(); return false;
 }
 var s = '', action = '', changes = [], ignored = [];

 if (uindex == 0) {
  if (!(uchanges & CHGD_FILE) && !(uchanges & CHGD_UURL)) { // shouldn't happen
   alert('Please specify a file or url'); form.file.focus(); return false;
  }

  action = 'create_upload';
  s = 'CREATE new';
  if (utype);
   s += ' ' + (utype == 'other' ? upload['ext'] : utype)
  s += ' upload\n"' + form.uttl.value + '"?\n';

  switch (utype) { // from file/url form fields...

   case 'image':
    if (uchanges & CHGD_UTTL) changes.push('title');
    if (uchanges & CHGD_CBIC) ignored.push('icon');
    if (uchanges & CHGD_CBCP) changes.push('caption');
    if (uchanges & CHGD_CBTH) changes.push('clickable');
    if (uchanges & CHGD_UURL) changes.push('url');
    if (uchanges & CHGD_FILE) changes.push('file');
    if (uchanges & CHGD_THMB) ignored.push('thumbnail');
    break;

   case 'video':
   case 'audio':
    if (uchanges & CHGD_UTTL) changes.push('title');
    if (uchanges & CHGD_CBIC) ignored.push('icon');
    if (uchanges & CHGD_CBCP) changes.push('caption');
    if (uchanges & CHGD_CBTH) ignored.push('clickable');
    if (uchanges & CHGD_UURL) {
     if (!(uchanges & CHGD_FILE)) changes.push('url');
     else                         ignored.push('url - using file');
    }
    if (uchanges & CHGD_FILE) changes.push('file');
    if (uchanges & CHGD_THMB) {
     if (utype == 'video') changes.push('thumbnail');
     else                  ignored.push('thumbnail');
    }
    break;

   case 'other':
    if (uchanges & CHGD_UTTL) changes.push('title');
    if (uchanges & CHGD_CBIC) changes.push('icon');
    if (uchanges & CHGD_CBCP) ignored.push('caption');
    if (uchanges & CHGD_CBTH) ignored.push('clickable');
    if (uchanges & CHGD_UURL) ignored.push('url');
    if (uchanges & CHGD_FILE) changes.push('file');
    if (uchanges & CHGD_THMB) ignored.push('thumbnail');
    break;

   default:
    if (uchanges & CHGD_UTTL) changes.push('title');
    if (uchanges & CHGD_CBIC) changes.push('icon');
    if (uchanges & CHGD_CBCP) changes.push('caption');
    if (uchanges & CHGD_CBTH) changes.push('clickable');
    if (uchanges & CHGD_UURL) changes.push('url');
    if (uchanges & CHGD_FILE) changes.push('file');
    if (uchanges & CHGD_THMB) changes.push('thumbnail');
    break;
  }
 }
 else { // modify existing
  action = 'modify_upload';
  s = 'MODIFY existing ' + (upload['type'] == 'other' ? upload['ext'] : upload['type']) + ' upload';

  if (utype && utype != upload['type'])
   s += ' (changing to ' + (utype == 'other' ? upload['ext'] : utype) + ')';
  s += '\n"' + upload['title'] + '"?\n';

  switch (utype) { // from file/url OR data...

   case 'image':
    if (!(uchanges & CHGD_FILE) && !upload['file']) { // ?
     alert('Please specify a file'); form.file.focus(); return false;
    }
    if (uchanges & CHGD_UTTL) changes.push('title');
    if (uchanges & CHGD_CBIC) ignored.push('icon');
    if (uchanges & CHGD_CBCP) changes.push('caption');
    if (uchanges & CHGD_CBTH) changes.push('clickable');
    if (uchanges & CHGD_UURL) changes.push('url');
    if (uchanges & CHGD_FILE) {
     changes.push('file');
     s += '\nFile on server will be REPLACED!\n';
    }
    if (uchanges & CHGD_THMB) ignored.push('thumbnail');
    break;

   case 'video':
   case 'audio':
    if (!(uchanges & CHGD_FILE) && !(uchanges & CHGD_UURL) && !upload['file'] && !upload['linkURL']) { // ?
     alert('Please specify a file or url'); form.file.focus(); return false;
    }
    if (uchanges & CHGD_UTTL) changes.push('title');
    if (uchanges & CHGD_CBIC) ignored.push('icon');
    if (uchanges & CHGD_CBCP) changes.push('caption');
    if (uchanges & CHGD_CBTH) ignored.push('clickable');

// FIXME...
    if (uchanges & CHGD_UURL) {
     if (!(uchanges & CHGD_FILE)) {
      changes.push('url');
      if (upload['file'])
       s += '\nFile on server will be DELETED!\n';
     }
     else {
      ignored.push('url - using file');
     }
    }
    if (uchanges & CHGD_FILE) {
     changes.push('file');
     if (upload['file'])
      s += '\nFile on server will be REPLACED!\n';
     if (upload['linkURL']) // else
      ignored.push('existing url - using file');
    }

    if (uchanges & CHGD_THMB && utype == 'video')
     changes.push('thumbnail');
    else if (uchanges & CHGD_THMB)
     ignored.push('thumbnail');
    break;

   case 'other':
    if (uchanges & CHGD_UTTL) changes.push('title');
    if (uchanges & CHGD_CBIC) changes.push('icon');
    if (uchanges & CHGD_CBCP) ignored.push('caption');
    if (uchanges & CHGD_CBTH) ignored.push('clickable');
    if (uchanges & CHGD_UURL) ignored.push('url');
    if (uchanges & CHGD_FILE) {
     changes.push('file');
     s += '\nFile on server will be REPLACED!\n';
    }
    if (uchanges & CHGD_THMB)
     ignored.push('thumbnail');
    break;

   default: // unknown type
    if (uchanges & CHGD_UTTL) changes.push('title');
    if (uchanges & CHGD_CBIC) changes.push('icon');
    if (uchanges & CHGD_CBCP) changes.push('caption');
    if (uchanges & CHGD_CBTH) changes.push('clickable');
    if (uchanges & CHGD_UURL) changes.push('url');
    if (uchanges & CHGD_FILE) {
     changes.push('file');
     s += '\nFile on server will be REPLACED!\n';
    }
    if (uchanges & CHGD_THMB) changes.push('thumbnail');
    break;
  }
 }
 s += (changes.length ? '\nChanged: '   + changes.join(', ') + '' : '');
 s += (ignored.length ? '\n(Ignoring: ' + ignored.join(', ') + ')': '');

 if (confirm(s)) {
  form.a.value = action;
  submit_form();
  return true;
 }
 return false;
}

//function clicked_upload() {
// alert('clicked_upload');clicked_upload_save();
//}

function clicked_delete() {
 //alert('clicked_delete');
 if (uindex == 0) { // shouldn't happen
  alert("Can't delete new uploads!"); return false;
 }
 if (!form.pass.value) {
  alert('Please enter your password!\n(Then re-submit form)'); pass_focus(); return false;
 }
 var action = 'delete_upload';
 var s = 'DELETE existing ' + (utype == 'other' ? upload['ext'] : utype) + ' upload\n"' + upload['title'] + '"?\n';
 if (upload['file'])
  s += '\nFile on server will be DELETED!\n';
 s += '\nAll references in «SimpleMarkup» will be removed';
 if (confirm(s)) {
  form.a.value = action;
  submit_form();
  return true;
 }
 return false;
}

function clicked_snapshot() {
 //alert('clicked_delete');
 var s = '', action = '';
 if (!form.pass.value) {
  alert('Please enter your password!\n(Then re-submit form)'); pass_focus(); return false;
 }
 action = 'snapshot';
 s += 'Make SNAPSHOT of entire site?\nThis can take a few moments...';
 if (confirm(s)) {
  form.a.value = action;
  submit_form();
  return true;
 }
 return false;
}

var SALT  = '2657a4d40463440d7f051561b1548ac17e93b2be';

function debug_info() {
 var a = [
  'page:\t'     + form.page.options[form.page.selectedIndex].value,
  'section:\t'  + form.sect.options[form.sect.selectedIndex].value,
  'position:\t' + form.posn.options[form.posn.selectedIndex].value,
  'upload:\t'   + form.list.options[form.list.selectedIndex].value,
  'changes:\t'  + uchanges
 ];
 return a.join('\n');
}


function submit_form() {
 var h = SHA1('' + nonce + SHA1(SALT + form.pass.value)); //alert([h,form.pass.value,SHA1(SALT + form.pass.value)])
 form.pass.value = h;
 form.sts.value = section.timestamp;
 form.uts.value =  upload.timestamp;
 //if (!confirm(debug_info())) return; // debug
 form.submit();
}

// util

function set_save_section() { //alert(schanges)
 var c = is_section_changed();
 var e = document.getElementById('savs_e');
 form.savs.disabled = !c;
 e.style.color = e.style.borderColor = c ? ENABLEDCOLOR : DISABLEDCOLOR;
}

function is_section_changed() { //alert([form.sttl.value,sindex])
 return (schanges && form.sttl.value);
}

function set_save_upload() { //alert([uchanges, uindex == 0, (uchanges & CHGD_FILE)])
 var c =   form.uttl.value && (
  (uchanges & CHGD_FILE) ||
  (uindex != 0 && (uchanges & (CHGD_UTTL|CHGD_CBCP|CHGD_CBTH|CHGD_CBIC|CHGD_THMB))) ||
  (uchanges & CHGD_UURL && (utype == 'video' || utype == 'audio' || utype == 'image')) // FIXME ? assume url ok
 );
 var e = document.getElementById('savu_e');
 form.savu.disabled = !c;
 e.style.color = e.style.borderColor = c ? ENABLEDCOLOR : DISABLEDCOLOR;
}

function set_delete_upload() {
 c = (uindex != 0);
 var e = document.getElementById('delu_e');
 form.delu.disabled = !c;
 e.style.color = e.style.borderColor = c ? ENABLEDCOLOR : DISABLEDCOLOR;
}


// cookie handling...

function Cookie() {
 // this.cookies;
 this.getNames = function() {
  var a = [];
  for (var name in this.cookies) a.push(name);
  return a;
 };
 this.get = function(name) {
  return name in this.cookies ? this.cookies[name].value : null;
 };
 this.set = function(name, value, days, domain, path, secure) {
  if (name in this.cookies) this.cookies[name].value = value;
  else this.cookies[name] = { value:value };
  var s = encodeURIComponent(name) + '=' + encodeURIComponent(value);
  if (days || days == 0) { this.cookies[name].days   = days;   s += '; max-age=' + days * 24 * 60 * 60; }
  if (domain)            { this.cookies[name].domain = domain; s += '; domain=' + domain; }
  if (path)              { this.cookies[name].path   = path;   s += '; path=' + path; }
  if (secure)            { this.cookies[name].secure = true;   s += '; secure'; }
  document.cookie = s;
 };
 this.unset = function(name) {
  if (this.get(name) === null) return;
  this.set(name, '', -1);
  delete this.cookies[name];
 };
 this._init = function() {
  this.cookies = {};
  var cookie = document.cookie;
  if (!cookie) return;
  var cookies = cookie.split('; ');
  for (var i = 0, n = cookies.length; i < n; i++) {
   var nv = cookies[i].split('=');
   if (nv.length != 2) continue;
   this.cookies[decodeURIComponent(nv[0])] = { value:decodeURIComponent(nv[1]) };
  }
 };
 this._init();
} // Cookie object usage: var c = new Cookie(); c.set(name, value); c.get(name);




String.prototype.ucfirst = function() {
 return this.replace(/[0-9a-z][-\'0-9a-z]*/ig, function(m) { return m.charAt(0).toUpperCase() + m.substring(1); });
}

String.prototype.titleCase = function() {
var re = /(?!^)\b(a|am|an|and|are|as|at|but|by|de|down|ere|for|from|has|in|into|is|near|nor|of|off|on|onto|or|out|over|per|so|than|the|to|unto|up|upon|van|via|von|with|yet)\b(?!$)/ig; // lc these words excluding first|last
 return this.ucfirst().replace(re, function(m) { return m.toLowerCase(); });
}

function kilomega(n, precision) {
 //n = parseInt(n);
 return (n > 1024 * 1024 * 1024 ?
  (Number(n / 1024 / 1024 / 1024).toPrecision(precision) + 'G') : n > 1024 * 1024 ?
  (Number(n / 1024 / 1024       ).toPrecision(precision) + 'M') :
  (Number(n / 1024              ).toPrecision(precision) + 'K'));
}


Array.prototype.desparse = function() {
 for (var i = 0, j = 0, a = [], n = this.length; i < n; i++)
  if (this[i] !== undefined) a[j++] = this[i];
 return a;
}

function data2arrays() { // pages/sections/upload objects to arrays - valid data format assumed
 var a = []
 for (var p in data.pages) {//alert([id,data.pages[id]['index']])
  if (!isNaN(p)) a[p] = data.pages[p];
  if (data.pages[p].is_static) data.pages[p].title += ' - NOT EDITABLE (but you might want its ID)';
 }
 data.pages = a.desparse();
 for (var i = 0, n = data.pages.length; i < n; i++) { //alert(data.pages[i].id)
  var a = [];
  if ('sections' in data.pages[i]) {
   for (var p in data.pages[i].sections) {
    if (!isNaN(p)) a[p] = data.pages[i].sections[p];
   }
  }
  a.unshift({title:'NEW Section...', blurb:'', timestamp:''});
  data.pages[i].sections = a.desparse();
 }
 var a = [{
  index:0, id:'', title:'NEW Upload...', file:'', type:'', ext:'', fileSize:'',
  imageW:'', imageH:'', thumb:'', thumbW:'', thumbH:'', thumbSize:'',
  linkURL:'', hasCaption:'', hasClickable:'', hasIcon:'', timestamp:''
 }];
 if ('uploads' in data) {
  for (var p in data.uploads) {
   var i = parseInt(p);
   if (p == i) {data.uploads[p].index = i + 1; a[i + 1] = data.uploads[p]; }
  }
 }
 data.uploads = a.desparse();
}

function pass_focus() {
 if (form.pass.value) return;
 window.cListObject._showItem(0,0); form.pass.focus();
}

// start here

function ee_init() {

 document.getElementById('incompatible').style.display = 'none';
 form = document.getElementById('f');

 data2arrays();

 var u = 0;
 for (var i in data.uploads) {
  if (data.uploads[i].fileSize)  u += 1 * data.uploads[i].fileSize;
  if (data.uploads[i].thumbSize) u += 1 * data.uploads[i].thumbSize;
 }
 usage = 'Quota: ' + kilomega(u, 3) + 'B / ' + kilomega(QUOTA, 3) + 'B';

 form.page.options.length = 0;
 for (var si = -1, i = 0, n = data.pages.length; i < n; i++) {
  form.page.add(new Option(data.pages[i].title, i, !!!i, !!!i), undefined);
  if (si == -1 && !data.pages[i].is_static) si = i;
 }

 form.page.selectedIndex = si == -1 ? 0 : si;

 clicked_by_az(); // populate uploaded files

 for (var i = 0, n = data.uploads.length; i < n; i++) {
  data.uploads[i].refs = 0;
  var id = data.uploads[i].id;
  for (var j = 0, n1 = data.pages.length; j < n1; j++)
   for (var k = 0, n2 = data.pages[j].sections.length; k < n2; k++) {
    var m = String(data.pages[j].sections[k].blurb).match(new RegExp('##(' + id + ')##', 'g'));
    if (m) data.uploads[i].refs += m.length;
   }
 }

 form.pass.disabled = false;
 form.pass.onchange = changed_pass;

 changed_pass(); changed_page(); changed_upload(); // temp - enables form even without password - better this way?

 form.page.onchange = changed_page;
 form.sect.onchange = changed_sect;
 form.sect.onkeyup  = changed_sect;
 form.sttl.onchange = changed_sect_title;
 form.blrb.onchange = changed_sect_blurb;
 form.posn.onchange = changed_sect_position;
 form.savs.onclick  = clicked_sect_save;

 form.list.onchange = changed_upload;
 form.list.onkeyup  = changed_upload;
 form.delu.onclick  = clicked_delete;

 form.uttl.onchange = changed_upload_title;
 form.cbcp.onchange = changed_upload_caption;
 form.cbth.onchange = changed_upload_clickable;
 form.cbic.onchange = changed_upload_icon;
 form.uurl.onchange = changed_upload_link;
 form.savu.onclick  = clicked_upload_save;

 form.file.onchange = changed_local;
 form.file.onkeyup = changed_local;
 form.thmb.onchange = changed_thumb;
 //form.upld.onclick  = clicked_upload;

 form.snap.onclick  = clicked_snapshot;

 var e = document.getElementById('bb');
 if (e) e.onclick = toggled_blurb_size;
 var e = document.getElementById('cst');
 if (e) e.onclick = clicked_sect_tcase;
 var e = document.getElementById('cut');
 if (e) e.onclick = clicked_upload_tcase;
 var e = document.getElementById('byd');
 if (e) e.onclick = clicked_by_date;
 var e = document.getElementById('bya');
 if (e) e.onclick = clicked_by_az;
 var e = document.getElementById('byt');
 if (e) e.onclick = clicked_by_type;
 var e = document.getElementById('chk');
 if (e) e.onclick = clicked_check_url;
 var e = document.getElementById('dump');
 if (e) e.onclick = clicked_dump_sm;

 for (var i = 0, n = form.elements.length; i < n; i++) {
  var e = form.elements[i];
  e.onfocus = function() { this.style.borderColor = ENABLEDCOLOR; };
  e.onblur  = function() { this.style.borderColor = DISABLEDCOLOR; };
 }

 var status = '', e = document.getElementById('status'), c = new Cookie(), s = c.get('easyedit_status');//location.search.substring(1);

 nonce = c.get('easyedit_session');

 //alert([c.getNames(), nonce])

 if (nonce === null) {
  status += 'Please <a href="editor.php">click here</a> to reload page.\nIf you get this message again, please allow session cookies in your browser, and retry.';
 }
 else if (s && e) {
  status += 'Status: ' + unescape(decodeURI(s)).replace(/\+\b/g, ' ');//decodeURI(s);
  c.unset('easyedit_status');
 }
 if (status) {
  e.innerHTML = '<pre style="color:#f99;font-style:italic;">' + status + '</pre>';
  e.style.display = 'inline';
 }

 var p = document.getElementsByTagName('dt')[0];
 if (p)
  p.addEventListener ? p.addEventListener('click', pass_focus, false) : p.attachEvent ? p.attachEvent('onclick', pass_focus) : null;
 //window.onfocus = pass_focus;
 //form.pass.autocomplete = 'off'; // see https://bugzilla.mozilla.org/show_bug.cgi?id=236791

 form.pass.focus();
 //pass_focus();

}

if (!iemac && document.getElementById && document.createElement) // crudely test browser capability
 window.addEventListener ? window.addEventListener('load', ee_init, false) : window.attachEvent ? window.attachEvent('onload', ee_init) : null;
