function mkb(bid,btitle,btxt) {
  return "<li><a id=b-"+bid+" href='javascript:;' title="+btitle+"><span>"+btxt+"</span></a></li>";
}

function cpLnk() {
  niov = "<p><a href="+$('aurl').value+">"+$('atxt').value+"</a> - <em>"+$('asite').value+"</em>";
  if ($('bwin').checked == true) niov += "<span class='wmp'>&nbsp;</span>";
  if ($('bqt').checked == true) niov += "<span class='qt'>&nbsp;</span>";
  if ($('bdivx').checked == true) niov += "<span class='divx'>&nbsp;</span>";
  if ($('bveoh').checked == true) niov += "<span class='veoh'>&nbsp;</span>";
  if ($('bad').checked == true) niov += "<span class='warn'>&nbsp;</span>";
  if ($('bc').checked == true) niov += "<span class='red'>&nbsp;</span>";
  return niov;
}

Ed = Class.create();

Ed.prototype = {
  initialize: function(nclass) {
    this.frmStyle = "<link rel='stylesheet' type='text/css' href="+frmStyle+" />";
    this.ei = '';
    urlp = location.href.split('/');
    this.pName = urlp[urlp.length-2]+'.'+urlp[urlp.length-1].replace(/[#|\?].*/,'');
    this.url = location.href +'?action=edit';
    this.nm = '';
    this.on = 0;
    this.nn = 0;
    this.n = $$('','div',nclass);
    this.n.each(function(ni,i) {
      ni.p = ni.parentNode;
      ni.a = ni.getElementsByTagName('a')[0];
      ni.a.href = 'javascript:;'; // Taking control of the launcher
      ni.ov = ni.getElementsByTagName('div')[0];
      ni.onmouseover = function() {
        this.clean();
        this.on = 1;
        this.timer();
        ni.className += ' on';
      }.bind(this);
      ni.onmouseout = function() {
        this.on = 0;
      }.bind(this);
      ni.a.onclick = function() {
        this.ei = i;
        this.on = 0;
        this.nn = 0;
        this.close();
        this.clean();
        ni.p.className = 'up';
        if (ni.p.id == 'links') {
          if (!this.ln) this.mkLn(i);
          else this.mvLn(i);
          $('brec').className = ''; 
          $('brec').innerHTML = 'Save';
        } else if (ni.p.id == 'profile') {
          if (!this.ptag) this.mkTag(i);
          else this.mvTag(i);
          $('trec').className = ''; 
          $('trec').innerHTML = 'Save';
        } else {
          if (!this.rte) this.mkRte(i);
          else this.mv(i);
          $('rec').className = ''; 
          $('rec').innerHTML = 'Save';
        }
      }.bind(this);
    }.bind(this));
    
    this.a = $$('main', 'span', 'add');
    this.a.each(function(ai,i) {
      ai.p = ai.parentNode;
      ai.a = ai.getElementsByTagName('a')[0];
      ai.a.href = 'javascript:;'; // Taking control of the launcher
      ai.onclick = function() {
        this.close();
        this.clean();
        if (ai.p.id == 'links') {
          this.nn = 1;
          this.ei = 0;
          if (!this.ln) this.mkLn(this.nn);
          else this.mvLn(this.nn);
          $('brec').className = ''; 
          $('brec').innerHTML = 'Save';
        } 
        if (ai.p.id == 'profile') {
          this.nn = 2;
          this.ei = 0;
          if (!this.ptag) this.mkTag(this.nn);
          else this.mvTag(this.nn);
          $('trec').className = ''; 
          $('trec').innerHTML = 'Save';
        } 
        if (ai.p.id == 'reviews') {
          this.nn = 3;
          this.ei = this.n.length - $$('reviews','div','s').length - 1;
          if (!this.rte) this.mkRte(this.nn);
          else this.mv(this.nn);
          $('rec').className = ''; 
          $('rec').innerHTML = 'Save';
        }
      }.bind(this);
    }.bind(this));
  },
  clean: function() {
    if (this.on == 1) {
      this.timer(); // Restart the timer if mouse is still over the section
      return;
    }
    for (i=0; i<this.n.length; i++) {
      this.n[i].className = (!this.n[i].className.match(/on/)) ? this.n[i].className : this.n[i].className.replace(/\son/,'');
    }
  },
  timer: function() {
    if (this.t) clearTimeout(this.t);
    this.t = setTimeout(this.clean.bind(this), 1600);
  },
  close: function() { 
    if (this.rte) this.rte.className = 'off';
    if (this.ln) this.ln.className = 'off';
    if (this.ptag) this.ptag.className = 'off';
    this.n[0].p.className = this.n[1].p.className = this.n[this.n.length-1].p.className = '';
  },
  mkRte: function(ii) {
    this.rte = document.createElement('div');
    this.rte.id = 'rte';
    if (this.nn != 3) this.n[ii].appendChild(this.rte);
    else this.a[this.a.length-1].p.appendChild(this.rte);
    hint = document.createElement('p');
    hint.id = 'hint';
    hint.innerHTML = "&gt; In advance, thanks for contributing to the page!";
    this.rte.appendChild(hint);
    
    this.cmds = document.createElement('ul');
    this.cmds.innerHTML = mkb('bold','bold','Bold') + mkb('italic','italic','Italic') + mkb('removeFormat','Remove All Formating','Unformat');
    this.cmds.innerHTML += "<li id='close'>Cancel</li><li id='rec'>Save</li>";
    this.rte.appendChild(this.cmds);
    
    this.mkEd(ii);
    
    nm = document.createElement('p');
    nm.id = 'auth';
    nm.innerHTML = "<input id='authnm' value='&rarr; Add your name' />";
    this.rte.appendChild(nm);
    
    $('authnm').onclick = function() { 
      $('authnm').value = ''; 
      $('authnm').className = ''; 
    }
    $('close').onclick = function(){
      this.close();
      this.fade(0);
    }.bind(this);
    $('rec').onclick = this.update.bind(this);
    this.b = this.lscmd();
    this.b.each(function(bi) {
      bi.onclick = function() {
        bcmd = bi.id.replace(/b-(.*)/gi,'$1');
        if (bcmd == 'createlink') {
          lnurl = prompt('Please enter a URL:', 'http://');
      		if (lnurl !=null && lnurl != '') this.ins(bcmd, lnurl);
        }
        else if (bcmd.match(/formatblock/)) {
          bh = bcmd.replace(/formatblock-/gi,'');
          this.ins('formatblock', '<'+bh+'>');
        }
        else {
          this.ins(bcmd, null);
        }
      }.bind(this);
    }.bind(this));
  },
  mkEd: function(ii) {
    this.ifrm = document.createElement('iframe');
    this.ifrm.id = 'rtefrm';
    this.ifrm.name = 'rtefrm';
    this.rte.appendChild(this.ifrm);
    this.idoc = frames[this.ifrm.name].document;
    this.sync(ii);
  },
  mkLn: function(ii) {
    this.ln = document.createElement('div');
    this.ln.id = 'ln';
    this.ln.style.marginTop = '-32px';
    if (this.nn != 1) this.n[ii].appendChild(this.ln);
    else this.a[0].p.appendChild(this.ln);
    this.ln.innerHTML = "<dl id='a'><dd><strong>URL:</strong><input id='aurl' class='tf' /></dd><dd><strong>Description:</strong><input id='atxt' class='tf' /></dd><dd>Place (i.e. YouTube...)<input id='asite' class='tf' /></dd></dl><dl><dt>Requirements:</dt><dd><input type='checkbox' class='tbox'  id='bwin'/>Windows Player</dd><dd><input type='checkbox'class='tbox' id='bqt'/>Quicktime</dd><dd><input type='checkbox' class='tbox' id='bdivx'/>DivX</dd><dd><input type='checkbox' class='tbox' id='bveoh'/>Veoh player</dd></dl><dl><dt>Flags:</dt><dd><input type='checkbox' class='tbox' id='bc'/>Possible copyrights infringement</dd><dd><input type='checkbox' class='tbox' id='bad'/>Lots of ads, ugly site</dd></dl><dl><dd class='cmds'><button id='brec'>Save</button><button id='brm'>Cancel</button></dd>";
    this.syncLn(ii);
    $('brm').onclick = this.close.bind(this);
    // $('brec').onclick = this.update.bind(this);
  },
  mkTag: function(ii) {
    this.ptag = document.createElement('div');
    this.ptag.id = 'ptag';
    this.ptag.style.marginTop = '-48px';
    if (this.nn != 2) this.n[ii].appendChild(this.ptag);
    else this.a[0].p.appendChild(this.ptag);
    this.ptag.innerHTML = "<dl id='t'><dd><strong>Tag:</strong><input id='dt' class='tf' /></dd><dd class='xl'><strong>Your review:</strong><input id='dd' class='tf' /></dd><dd class='cmds'><button id='trec'>Save</button><button id='trm'>Cancel</button></dd></dl>";
    this.syncTag(ii);
    $('trm').onclick = this.close.bind(this);
    $('trec').onclick = this.update.bind(this);
  },
  lscmd: function() {
    var arrb = new Array(this.cmds.getElementsByTagName('a').length);
    for (i=0; i<arrb.length; i++) { arrb[i] = this.cmds.getElementsByTagName('a')[i]; }
    return arrb;
  },
  ins: function(cmd, options) {
    if (!document.all) this.ifrm.contentDocument.execCommand(cmd, false, options);
    else this.idoc.execCommand(cmd, false, options);
    this.ifrm.contentWindow.focus();
  },
  mv: function(ii) {
    if (this.nn != 3) this.n[ii].appendChild(this.rte);
    else this.a[this.a.length-1].p.appendChild(this.rte);
    this.rte.className = 'eform';
    if (this.nm != '') $('authnm').value = this.nm;
    this.sync(ii);
  },
  mvLn: function(ii) {
    if (this.nn != 1) this.n[ii].appendChild(this.ln);
    else this.a[0].p.appendChild(this.ln);
    this.ln.className = '';
    this.syncLn(ii);
  },
  mvTag: function(ii) {
    if (this.nn != 2) this.n[ii].appendChild(this.ptag);
    else this.a[0].p.appendChild(this.ptag);
    this.ptag.className = '';
    this.syncTag(ii);
  },
  sync: function(ii) {
    if (this.nn != 3) {
      this.ifrm.style.height = (this.n[ii].ov.offsetHeight-20>20) ? this.n[ii].ov.offsetHeight+'px' : '80px';
      this.rte.style.marginTop = '-'+(this.n[ii].ov.offsetHeight+20)+'px';
      intxt = this.n[ii].ov.innerHTML.replace(/\n/gi,'[nl]');
      intxt = intxt.replace(/<span.*?>/gi,'').replace(/<\/span>/gi,'');
      intxt = intxt.replace(/<a.*?>/gi,'').replace(/<\/a>/gi,'');
      intxt = intxt.replace(/\[nl\]/gi,"\n");
    } else {
      this.ifrm.style.height = '100px';
      this.rte.style.marginTop =  '-'+(this.a[1].p.offsetHeight-40)+'px';
      intxt = '';
    }
    if (!document.all) {
      this.ifrm.contentDocument.designMode = 'on';
      this.ifrm.contentDocument.open();
      this.ifrm.contentDocument.write(this.frmStyle + intxt);
      this.ifrm.contentDocument.close();
      this.ifrm.contentDocument.execCommand('styleWithCSS', false, false);
    } else {
      this.idoc.designMode = 'on';
      this.idoc.open();
      this.idoc.write(this.frmStyle + intxt);
      this.idoc.close();
    }
    this.ifrm.contentWindow.focus();
  },
  syncLn: function(ii) {
    $('bc').checked = $('bad').checked = false;
    $('bveoh').checked = $('bwin').checked = $('bqt').checked = $('bdivx').checked = false;
    $('aurl').value = $('atxt').value = $('asite').value = '';
    if (this.nn == 1) {
      this.ln.style.marginTop = '-'+(this.a[0].p.offsetHeight-40)+'px';
    } else {
      this.ln.style.marginTop = '-32px';
      if (this.n[ii].ov.getElementsByTagName('a').length > 0) {
        $('aurl').value = this.n[ii].ov.getElementsByTagName('a')[0].href;
        $('atxt').value = this.n[ii].ov.getElementsByTagName('a')[0].innerHTML.replace(/<span.*?>/gi,'').replace(/<\/span>/gi,'').replace(/<a.*?>/gi,'').replace(/<\/a>/gi,'');
      }
      if (this.n[ii].ov.getElementsByTagName('em').length > 0)
        $('asite').value = this.n[ii].ov.getElementsByTagName('em')[0].innerHTML.replace(/<span.*?>/gi,'').replace(/<\/span>/gi,'').replace(/<a.*?>/gi,'').replace(/<\/a>/gi,'');
      if (this.n[ii].ov.getElementsByTagName('span').length > 0) {
        flgs = this.n[ii].ov.getElementsByTagName('span');
        for (i = 0; i < flgs.length; i++) {
          if (flgs[i].className == 'red') $('bc').checked = true;
          if (flgs[i].className == 'warn') $('bad').checked = true;
          if (flgs[i].className == 'veoh') $('bveoh').checked = true;
          if (flgs[i].className == 'wmp') $('bwin').checked = true;
          if (flgs[i].className == 'qt') $('bqt').checked = true;
          if (flgs[i].className == 'divx') $('bdivx').checked = true;
        }
      }
    }
  },
  syncTag: function(ii) {
    $('dt').value = $('dd').value = '';
    if (this.nn != 2) {
      this.ptag.style.marginTop = '-48px';
      $('dt').value = this.n[ii].ov.getElementsByTagName('dt')[0].innerHTML.replace(/<span.*?>/gi,'').replace(/<\/span>/gi,'').replace(/<a.*?>/gi,'').replace(/<\/a>/gi,'');
      $('dd').value = this.n[ii].ov.getElementsByTagName('dd')[0].innerHTML.replace(/:\s/,'').replace(/<span.*?>/gi,'').replace(/<\/span>/gi,'').replace(/<a.*?>/gi,'').replace(/<\/a>/gi,'');
    } else this.ptag.style.marginTop = '-'+(this.a[0].p.offsetHeight-64)+'px';
  },
  update: function() {
    if (this.nn == 0) pid = this.n[this.ei].p.id;
    else if (this.nn == 1 || this.nn == 2) pid = this.a[0].p.id;
    else pid = this.a[this.a.length-1].p.id;
    if (pid != 'links' && pid != 'profile') {
      if (/name/.test($('authnm').value)) {
        $('authnm').className = 'stress';
        return;
      } else this.nm = $('authnm').value;
      idoc = (!document.all) ? this.ifrm.contentDocument.body.innerHTML : this.idoc.body.innerHTML;
      etxt = this.toWiki(idoc.replace(/\n/g,'')).replace(/\n*$/gi,'').replace(/^\n*/gi,'') + "\n";
      if (pid == 'title') {
        etxt += "\n(:div3end:)";
        etxt += (/Videos/.test(this.pName)) ? "\n(:div3 id=links:)\nh2. Where to watch it\n" : "\n(:div3 id=profile:)\nh2. Participatory reviews\n";
      }
      $('rec').innerHTML = 'Saving...';
      $('rec').className = 'busy';
    } 
    else {
      if (pid == 'links') {
        this.nm = 'NoName';
        if (!$('aurl').value || !$('atxt').value || !$('asite').value) {
          $('a').className = 'stress';
          return;
        } else etxt = "[[" + $('aurl').value + "|" + $('atxt').value + "]]" + " - _" + $('asite').value + "_";
        if ($('bwin').checked == true) etxt += '(:wmp:)';
        if ($('bqt').checked == true) etxt += '(:qt:)';
        if ($('bdivx').checked == true) etxt += '(:divx:)';
        if ($('bveoh').checked == true) etxt += '(:veoh:)';
        if ($('bc').checked == true) etxt += '(:red:)';
        if ($('bad').checked == true) etxt += '(:warn:)';
        etxt += "\n";
        if (this.ei == $$('links','div','s').length) 
          etxt += "(:div3end:)\n(:div3 id=reviews:)\nh2. Reviews\n";
        $('brec').innerHTML = 'Saving...';
      } else {
        this.nm = 'NoName';
        if (!$('dt').value || !$('dd').value) {
          this.ptag.className = 'stress';
          return;
        } else {
          etxt = ":"+$('dt').value+":: "+$('dd').value+"\n";
        }
        if (this.ei == $$('profile','div','s').length) 
          etxt += "(:div3end:)\n(:div3 id=reviews:)\nh2. Related Sites\n";
        $('trec').innerHTML = 'Saving...';
        alert(etxt);
      }
    }
        
    edata = "action=edit"
      + "&n=" + this.pName
      + "&text=" + encodeURI(etxt)
      + "&author=" + encodeURI(this.nm)
      + "&s=" + (this.ei + 1)
      + "&live=1&post=1";
    if (this.nn != 0) edata += "&ni=" + this.nn;
    
    this.mkXReq();
    this.xreq.onreadystatechange = function() { 
      if (this.xreq.readyState == 4) { if (this.xreq.status == 200) {
        if (this.nn != 0) {
          if (this.nn == 1) {
            ns = document.createElement('div');
            ns.className = 's';
            ns.innerHTML = "<span class='ed'><a href='javascript:;'>edit <span>&nbsp;</span></a></span><div class='inner'>" + cpLnk() + "</div>";
            this.a[0].p.insertBefore(ns, this.n[1]);
          } 
          else if (this.nn == 2) {
            ntag = document.createElement('div');
            ntag.className = 's';
            ntag.innerHTML = "<span class='ed'><a href='javascript:;'>edit <span>&nbsp;</span></a></span><div class='inner' ><dl><dt>"+$('dt').value+"</dt><dd>: "+$('dd').value+"</dd></dl></div>";
            this.a[0].p.insertBefore(ntag, this.n[1]);
          }
          else if (this.nn == 3) {
            ncom = document.createElement('div');
            ncom.className = 's';
            ncom.innerHTML = (!document.all) ? this.ifrm.contentDocument.body.innerHTML : this.idoc.body.innerHTML;
            scom = $$('reviews','div','s');
            if (!scom) {
              this.a[1].p.appendChild(ncom);
            } else this.a[1].p.insertBefore(ncom, scom[0]);
          }
          this.n = $$('','div','s');
        } else {
          if (this.n[this.ei].p.id == 'links') {
            this.n[this.ei].ov.innerHTML = cpLnk() + "</p>";
          } else if (this.n[this.ei].p.id == 'profile') {
            this.n[this.ei].ov.innerHTML = "<dl><dt>"+$('dt').value+"</dt><dd>: "+$('dd').value+"</dd></dl>";
          } else {
            this.n[this.ei].ov.innerHTML = (!document.all) ? this.ifrm.contentDocument.body.innerHTML : this.idoc.body.innerHTML;
          }
        }
        this.close();
      } else { alert('There was a problem with the request.'); } }
    }.bind(this);
    
    this.xreq.open('POST', this.url, true);
    this.xreq.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    this.xreq.send(edata);
  },
  toWiki: function(html) {
    html = html.replace(/<p>\s*&nbsp;\s*<\/p>/gi,'');
    html = html.replace(/<p>(.*?)<\/p>/gi,"[nl]$1[nl]"); 
    html = html.replace(/<(\/?)i>/gi,"<$1em>");
    html = html.replace(/<em>(.*?)<\/em>/gi,"_$1_");
    html = html.replace(/<(\/?)b>/gi,"<$1strong>");
    html = html.replace(/<strong>(.*?)<\/strong>/gi,"*$1*");
    html = html.replace(/<ul>(.*?)<\/ul>/gi, function($1){
      $1 = $1.replace(/<br>/gi, '[br]');
      return $1.replace(/(<\/li>)/gi,'[nl]').replace(/<li>/gi, '* ').replace(/<ul>(.*?)<\/ul>/gi, '[nl]$1');
    });
    html = html.replace(/<ol>(.*?)<\/ol>/gi, function($1){
      $1 = $1.replace(/<br>/gi, '[br]');
      return $1.replace(/(<\/li>)/gi,'[nl]').replace(/<li>/gi, '# ').replace(/<ol>(.*?)<\/ol>/gi, '[nl]$1');
    });
    html = html.replace(/<a\b[^>]*href="([^"]*)">([^<]*)<\/a>/gi, '[[$1|$2]]');
    html = html.replace(/<br><br>\s*/gi, '[nl][nl]');
    html = html.replace(/<br>\s*/gi, '');
    html = html.replace(/^\s*/gi, '');
    html = html.replace(/\s*$/gi, '');
    html = html.replace(/\[nl\]\s*/gi, "\n");
    html = html.replace(/\[br\]\s*/gi, "\\\\\n");
    
    return html;
  },
  mkXReq: function() {
    if (window.XMLHttpRequest) {
      this.xreq = new XMLHttpRequest();
      this.xreq.overrideMimeType('text/html');
    }
    else if (window.ActiveXObject) {
      var aVer = [ "MSXML2.XMLHttp.5.0",
        "MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0",
        "MSXML2.XMLHttp","Microsoft.XMLHttp"];
      for (var i = 0; i < aVer.length; i++) {
        try { this.xreq = new ActiveXObject(aVer[i]); } 
        catch (e) {}
      }
    }
    if (!this.xreq) {
      alert('We had a little problem to save your edit.');
      return false;
    }
  }
}

window.onload = function() {
  frmStyle = 'http://zeboudoir.org/pub/skins/ottoman/includes/ifrm.css';
  new Ed('s',frmStyle);
}
