function Display() {
  this.ctr_ = 0;
}

Display.getInstance = function () {
  if (!Display.singleton_) {
    Display.singleton_ = new Display();
  }
  return Display.singleton_;
}

Display.prototype.changed = function () {
  $(document.body).addClassName("changed");
}

Display.prototype.lock = function () {
  if (this.ctr_ ++ == 0) {
    $(document.body).addClassName("waiting");
  }
}

Display.prototype.unlock = function () {
  if (-- this.ctr_ == 0) {
    $(document.body).removeClassName("waiting");
  }
}

Display.prototype.addMessage = function (theMessage) {
  var li = new Element("li");
  li.update(theMessage.escapeHTML());
  $('message').appendChild(li);
  $('message').show();

  (function () {
    li.remove();
    if ($('message').empty()) {
      $('message').hide();
    }
  }).delay(5);
}

Display.prototype.refresh = function () {
  var hash = location.hash;
  var search = location.search || "?";
  var pathname = location.pathname;
  search = search.replace(/((?:\?|\&)q_ck=)(\w+)(\&|$)|((?:\?)(?:$))|($)/, function (m, m1, m2, m3, m4, m5) {
    if (m2) {
      return m1 + new Date().valueOf().toString(36) + m3;
    }
    else if (m4) {
      return "?q_ck=" + new Date().valueOf().toString(36);
    }
    else {
      return "&q_ck=" + new Date().valueOf().toString(36);
    }
  });

  location.replace(pathname + search + hash);
}

// ============================================================================
function _submit(theForm) {
  Display.getInstance().lock();
  new Ajax.Request(theForm.readAttribute('action'),
                   {method: 'post',
                    parameters: theForm.serialize(),
                    onSuccess: function (response) {
                      Display.getInstance().unlock();
                      if (response.responseText) {
                        alert(response.responseText);
                      }
                      Display.getInstance().refresh();
                    },
                    onFailure: function (response) {
                      Display.getInstance().unlock();
                      alert('Ein Fehler ist aufgetreten. Die Seite wird neu geladen.');
                      Display.getInstance().refresh();
                    }
                   });
  return false;
}

function _logout() {
  Display.getInstance().lock();
  new Ajax.Request('.',
                   {method: 'post',
                    parameters: {action: 'logout'},
                    onSuccess: function (response) {
                      Display.getInstance().unlock();
                      if (response.responseText) {
                        alert([response.responseText].join('\n'));
                      }
                      Display.getInstance().refresh();
                    },
                    onFailure: function (response) {
                      Display.getInstance().unlock();
                      alert('Ein Fehler ist aufgetreten. Die Seite wird neu geladen.');
                      Display.getInstance().refresh();
                    }
                   });
  return false;
}

function _add(theForm, theType) {
  var template_id = theType + '_template';
  new Ajax.Request('.',
                   {method: 'post',
                    parameters: theForm.serialize(),
                    onCreate: function () {
                      Display.getInstance().lock();
                    },
                    onComplete: function () {
                      Display.getInstance().unlock();
                    },
                    onSuccess: function (response) {
                      var match = response.responseText.match(/^id=(\d+)$/);
                      if (match) {
                        var placeholder = {id: match[1],
                                           caption: theForm.caption.value};
                        var template = new Template($(template_id).innerHTML, /([\s\S]?)(%(\w+)%)/).evaluate(placeholder);
                        $(template_id).up('ul').appendChild(new Element('li').update(template));
                      }
                      else if (response.responseText) {
                        alert(response.responseText);
                      }
                      else {
                        alert("Unbekannter Fehler");
                      }
                    },
                    onFailure: function (response) {
                      alert('Ein Fehler ist aufgetreten. Die Seite wird neu geladen.');
                      Display.getInstance().refresh();
                    }
                   });
  return false;
}

function _rem(theButton, theType, theId) {
  new Ajax.Request('.',
                   {method: 'post',
                    parameters: {action: '_rem' + theType.capitalize(),
                                 id: theId},
                    onCreate: function () {
                      Display.getInstance().lock();
                    },
                    onComplete: function () {
                      Display.getInstance().unlock();
                    },
                    onSuccess: function (response) {
                      if (response.responseText == '0' || response.responseText == '1') {
                        $(theButton).up('li').remove();
                      }
                      else if (response.responseText) {
                        alert(response.responseText);
                      }
                    },
                    onFailure: function (response) {
                      alert('Ein Fehler ist aufgetreten. Die Seite wird neu geladen.');
                      Display.getInstance().refresh();
                    }
                   });
  return false;
}

function _change(theValue, theType) {
  Display.getInstance().lock();
  new Ajax.Request('.',
                   {method: 'post',
                    parameters: {action: theType == 'album' ? '_changeAlbum' : '_change',
                                 value: theValue},
                    onSuccess: function (response) {
                      Display.getInstance().unlock();
                      if (theType == 'album') {
                        Display.getInstance().refresh();
                      }
                      else {
                        $('info_' + Math.abs(theValue)).update(response.responseText);
                        Display.getInstance().changed();
                      }
                    },
                    onFailure: function (response) {
                      Display.getInstance().unlock();
                      alert('Ein Fehler ist aufgetreten. Die Seite wird neu geladen.');
                      Display.getInstance().refresh();
                    }
                   });
  return false;
}

function _onchange(theElement) {
  var match = theElement.name.match(/(?:^category_of_sticker_(\d+)$)|(_toggleAlbum|_toggleCategory|_toggleSticker)/);
  if (!match) {
    alert("Unknown action: name=\"" + theElement.name + "\", value=\"" + theElement.value + "\"");
    Display.getInstance().refresh();
    return;
  }

  var ajax_params = {method: 'post'};
  ajax_params.onCreate = function () {
    Display.getInstance().lock();
  }
  ajax_params.onComplete = function (response) {
    Display.getInstance().unlock();
  }
  ajax_params.onFailure = function (response) {
    alert('Ein Fehler ist aufgetreten. Die Seite wird neu geladen.');
    if (response.responseText) {
      alert(response.responseText);
    }
    Display.getInstance().refresh();
  }

  if (match[1]) {
    ajax_params.onSuccess = function (response) {
      Display.getInstance().refresh();
    };
    ajax_params.parameters = {action: '_changeStickerCategory', sticker: match[1], category: theElement.value};
  }
  else if (match[2]) {
    ajax_params.parameters = {action: match[2], id: theElement.value, active: theElement.checked};
  }

  new Ajax.Request('.', ajax_params);
}

onload = function () {
  $$(".editable").each(function (anElement) {
    var pars = anElement.identify().match(/^(album|category|sticker)_(caption)_(\d+)$/);
    if (pars == null) {
      return;
    }
    function callback(form, value) {
      Display.getInstance().lock();
      return ["action=modify_" + pars[1] + "_" + pars[2],
              "id=" + pars[3],
              "caption=" + encodeURIComponent(value)].join("&");
    }
    function onComplete(response) {
      Display.getInstance().unlock();
    }
    function onFailure(response) {
      alert('Ein Fehler ist aufgetreten. Die Seite wird neu geladen.');
      Display.getInstance().refresh();
    }
    new Ajax.InPlaceEditor(anElement.identify(),
                           ".",
                           {callback: callback,
                            onComplete: onComplete,
                            onFailure: onFailure});
  });
}

