/*===========================================================================
  INITIALISATION & ETC
---------------------------------------------------------------------------*/
function flashNoticeCheck() {
  if (typeof flashNotices == 'undefined') {
    return;
  }
  for (var id in flashNotices) {
    var notice = document.createElement('p');
    notice.innerHTML = flashNotices[id];
    notice.id = id;
    notice.style.display = 'none';
    var sidebar = $$('.sidebar')[0];
    if (sidebar) {
      sidebar.insertBefore(notice, sidebar.firstChild);
      Effect.Appear(id, {duration:0.2});
    }
  }
}

Event.observe(window, 'load', flashNoticeCheck);

/*===========================================================================
  ADMIN-WIDE UI ACTIONS
---------------------------------------------------------------------------*/
function viewSite(url) {
  var frame = $('viewSiteFrame');
  var cntr = frame.up('div');
  var maxW = document.body.offsetWidth - 56;
  var step = maxW / 10;

  var slideIn = function () {
    var currW = 0;
    frame.style.overflow = 'hidden';
    cntr.style.display = 'block';
    var slideTimer = setInterval(
      function () {
        var newW = currW + step;
        if (newW >= maxW) {
          newW = maxW;
          frame.style.overflow = 'auto';
          clearTimeout(slideTimer);
        }
        cntr.style.width = newW + "px";
        currW = newW;
      },
      20
    );
  }

  var slideOut = function () {
    window.previewing = false;
    frame.setAttribute('src', 'about:blank');
    frame.style.overflow = 'hidden';
    var currW = parseFloat(cntr.style.width);
    var slideTimer = setInterval(
      function () {
        var newW = currW - step;
        if (newW <= 0) {
          newW = 0;
          cntr.style.display = "none";
          clearTimeout(slideTimer);
        }
        cntr.style.width = newW + "px";
        currW = newW;
      },
      20
    );
  }

  if (!window.previewing) {
    window.previewing = true;
    if (url) {
      changeViewSiteUrl(url);
    } else {
      cntr.addClassName('viewLoading');
    }
    try {
      cntr.style.height = (window.innerHeight - 30) + "px";
    } catch(e) {
      cntr.style.height = (document.documentElement.clientHeight - 30) + "px";
    }
    cntr.style.width = 0;

    var overlay = $(document.createElement('div'));

    var slideFn = function (e) {
      Event.stopObserving($('viewSiteTag'), 'click', slideFn);
      Event.stopObserving($('viewSiteTag'), 'mouseout', dragFn);
      slideIn();
      Event.stop(e);
    }

    var extractFn = function (e) {
      cntr.style.display = 'block';
      var x = Event.pointerX(e);
      x += 16;
      var newW = Math.min(document.body.offsetWidth - x, maxW);
      cntr.style.width = newW + "px";
      Event.stop(e);
    }

    var retractFn = function (e) {
      Event.stopObserving(overlay, 'mousemove', extractFn);
      Event.stopObserving(overlay, 'mouseup', retractFn);
      Event.stopObserving(overlay, 'mouseout', retractFn);
      overlay.remove();
      slideOut();
      Event.stop(e);
    }

    var dragFn = function(e) {
      Event.stopObserving($('viewSiteTag'), 'click', slideFn);
      Event.stopObserving($('viewSiteTag'), 'mouseout', dragFn);

      document.body.appendChild(overlay);
      overlay.setStyle({
        position: 'absolute',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%'
      });

      Event.observe(overlay, 'mousemove', extractFn);
      Event.observe(overlay, 'mouseup', retractFn);
      Event.observe(overlay, 'mouseout', retractFn);
      Event.stop(e);
    }

    Event.observe($('viewSiteTag'), 'click', slideFn);
    Event.observe($('viewSiteTag'), 'mouseout', dragFn);
  } else {
    slideOut();
  }
  return false;
}

function changeViewSiteUrl(url) {
  var frame = $('viewSiteFrame');
  frame.up('div').addClassName('viewLoading');
  //alert("previewing: " + url);
  frame.setAttribute('src', url);
}

/*============================================================================
  Standard display representations of time
----------------------------------------------------------------------------*/
function stdTimeString(d) {
  var H = d.getHours();
  var M = d.getMinutes();
  var p = H < 12 ? "am" : "pm";
  if (H > 12) { H -= 12; }
  if (M < 10) { M = "0"+M;}
  return H + ":" + M + p;
}

function stdDateString(dt) {
  var days = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
  var months = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
  var a = days[dt.getDay()];
  var d = dt.getDate();
  var b = months[dt.getMonth()];
  var Y = dt.getYear() + 1900;
  return a + " " + d + " " + b + " " + Y;
}

function stdDateTimeString(d) {
  return d ? stdTimeString(d) + ", " + stdDateString(d) : "";
}

function biasedDateTimeString(d) {
  d = d || new Date();
  if (stdDateString(d) == stdDateString(new Date())) {
    return stdTimeString(d);
  } else {
    return stdDateTimeString(d);
  }
}

/*=============================================================================
  NESTED COLLECTIONS
  Generic support for editing multiple associations
-----------------------------------------------------------------------------*/
// Inserts a new form at the bottom of the list
function addThisNestedParamForm(npListElem, fields, options) {
  options = options || {};
  npListElem = $(npListElem);
  var klass = (options.className ? 'class="'+options.className+'"' : '');
  var id = (options.id ? 'id="'+options.id+'"' : '');
  var item = '<li '+klass+ ' ' + id +'>'+fields+'</li>';
  subs = options['substitutions'] || {};
  var index = subs["NEW_RECORD"] = subs["NEW_RECORD"] || new Date().getTime();
  for (key in subs) {
    item = item.replace(new RegExp(key, 'g'), subs[key]);
  }
  npListElem.insert({bottom: item});
  if (npListElem.hasClassName('sortableList')) {
    makeNestedCollectionSortable(npListElem);
  }
  return index;
}


// Sets the value of the deleted field to 1 if it exists.
// Hides the elem.
function removeThisNestedParamForm(remBtn) {
  var li = $(remBtn).up('li');

  // Disable all fields.
  toggleFieldsIn(li, false);

  // Set the delete flag.
  var inp = li.down('input.deleteFlag');
  inp.value = true;

  // Re-enable the delete flag field.
  inp.removeAttribute('disabled');

  // Hide the form.
  li.hide();
}


function makeNestedCollectionSortable(list) {
  Sortable.create(
    list,
    { onUpdate: function () { updateNestedCollectionPositions(list) } }
  );
  updateNestedCollectionPositions(list);
}


function updateNestedCollectionPositions(list) {
  list = $(list);
  Sortable.sequence(list).each(function (id, position) {
    var field = list.down("#"+list.id+"Item_"+id+" input[id$=_position]");
    field.value = position;
  });
}


/*===========================================================================
  SORTABLE NESTED LISTS
---------------------------------------------------------------------------*/
function sortableCollection(list, options) {
  list = $(list);
  options = options || {};
  options.posFieldClass = options.posFieldClass || 'positionField';
  var updateListPositionFields = function () {
    var index = -1;
    list.select('.'+options.posFieldClass).each(function (field) {
      field.value = index += 1;
    });
  }

  // Do it once immediately.
  updateListPositionFields();

  // Do it again when the order changes.
  options.onChange = updateListPositionFields;
  Sortable.create(list, options);
}


// Appends a query string of options to path - option values when converted to
// a string should not be blank.
function urlWithParams(path, options) {
  options = $H(options);
  options.each(function (pair) {
    var v = pair.value;
    if (v == '' || v == null || typeof(v) == 'undefined') {
      options.unset(pair.key);
    }
  });
  if (options.size() > 0) {
    return path + '?' + options.toQueryString();
  } else {
    return path;
  }
}


/* SIMPLE, RAILS-LIKE FIELD CREATION */
function hiddenFieldFor(objType, methodName, index, value) {
  return inputFieldFor(objType, methodName, index, 'hidden', value);
}

function inputFieldFor(objType, methodName, index, type, value) {
  var atts = { type: type, value: value };
  return fieldFor(objType, methodName, index, 'input', atts);
}

function fieldFor(objType, methodName, index, tag, attributes) {
  attributes = attributes || {};
  if (index) {
    attributes.id = objType + "_" + index + "_" + methodName;
    attributes.name = objType + "[" + index + "][" + methodName + "]";
  } else {
    attributes.id = objType + "_" + methodName;
    attributes.name = objType + "[" + methodName + "]";
  }
  return newElement(tag, null, attributes);
}

function newElement(tagName, content, attributes) {
  var elem = $(document.createElement(tagName));

  if (content) {
    elem.update(content);
  }

  if (attributes) {
    var props = $A(['id', 'className', 'type', 'value']);
    props.each(function (prop) {
      if (attributes[prop]) {
        elem[prop] = attributes[prop];
        attributes[prop] = null;
      }
    });

    for (var att in attributes) {
      if (attributes[att]) {
        elem.setAttribute(att, attributes[att]);
      }
    }
  }

  return elem;
}

function resetField(field) {
  var input = document.createElement('input');
  input.type = field.type;
  input.id = field.id;
  input.className = field.className;
  input.name = field.name;
  input.size = field.getAttribute("size");
  input.onchange = field.onchange;
  field.parentNode.insertBefore(input, field);
  Element.remove(field);
  SI.Files.stylizeAll();
  return input;
}

function toggleFieldsIn(block, enabled) {
  block = $(block);
  block.select('input, textarea, select').each(function(elem) {
    if (!enabled) {
      elem.setAttribute('disabled', 'disabled');
    } else if (elem.getAttribute('disabled')) {
      elem.removeAttribute('disabled');
    }
  });
}


/* TAG SUPPORT */

// Available options:
// - count
// - deleteCallback
// - add (adds 1 to the count, even if retrieving count via ajax)
function buildTag(phrase, options) {
  options = options || {};

  // This logic is mirrored server-side as well.
  phrase = phrase.toLowerCase().stripTags().strip();
  if (!phrase) { return; }


  var tag = $(document.createElement('span'));
  tag.className = "tag";

  // decoration
  tag.decoration = document.createElement('img');
  tag.appendChild(tag.decoration);
  tag.decoration.className = 'decoration';
  tag.decoration.src = "/images/generic/bg_tag_left.gif";

  // phrase
  tag.phrase = document.createTextNode(phrase);
  tag.appendChild(tag.phrase);
  tag.phraseText = phrase;

  // count
  tag.count = document.createElement('span');
  tag.appendChild(tag.count);
  tag.count.className = "count";
  if (typeof options.count != 'undefined') {
    var count = options.add ? options.count + 1 : options.count;
    count = Math.max(count, 1);
    var num = document.createTextNode(count);
    tag.count.appendChild(num);
  } else {
    var spinner = document.createElement('img');
    spinner.src = "/images/generic/spinner_tiny.gif";
    tag.count.appendChild(spinner);
    new Ajax.Updater(
      tag.count,
      '/admin/settings/count_tags',
      {
        parameters: { 'phrase': phrase, 'add': (options.add ? 1 : 0) }
      }
    );
  }

  // optional delete link
  if (options.deleteCallback) {
    tag.delLink = document.createElement('img');
    tag.appendChild(tag.delLink);
    tag.delLink.src = "/images/generic/icon_tag_delete.gif";
    tag.delLink.owner = tag;
    tag.delLink.className = "tagDelete";
    Event.observe(tag.delLink, 'click', options.deleteCallback);
  }

  return tag;
}


/* A hack to make uploads not hang in Safari. Just call this
 * immediately before the upload is submitted. This does an Ajax call to
 * the server, which returns an empty document with the "Connection: close"
 * header, telling Safari to close the active connection. A hack, but
 * effective. */
function closeKeepAlive() {
  if (/AppleWebKit|MSIE/.test(navigator.userAgent)) {
    new Ajax.Request("/admin/ping/close", { asynchronous:false });
  }
}


ImageOrFileField = function (box, bPopulated, bAutoSubmit) {
  box = $(box);

  box.image = box.down('.ioffImage');
  box.uploadBox = box.down('.ioffUpload');
  box.fileField = box.uploadBox.down('input[type="file"]');
  box.detailsBox = box.down('.ioffDetails');
  box.detailsBox.submitting = box.detailsBox.down('p.submitting');
  box.detailsBox.saved = box.detailsBox.down('p.saved');
  box.idField = box.detailsBox.down('input.idField');
  box.idField.originalValue = box.idField.value;

  box.populatedSrc = bPopulated ? box.image.getAttribute('src') : false;
  box.bUploading = !box.populatedSrc;
  box.bAutoSubmit = bAutoSubmit && typeof(Draftability) != 'undefined';

  var init = function () {
    toggleUploadOrDetails(!box.populatedSrc, true);
    Event.observe(box.image, 'click', clickImage);
    monitorChanges();
  }

  var toggleUploadOrDetails = function (showUpload, showSaved) {
    if (showUpload) {
      box.bUploading = true;
      box.detailsBox.hide();
      box.uploadBox.show();
      if (box.bAutoSubmit) {
        toggleFieldsIn(box.uploadBox, true);
      }
      box.idField.value = '';
    } else {
      box.bUploading = false;
      box.uploadBox.hide();
      if (showSaved) {
        box.detailsBox.saved.show();
        box.detailsBox.submitting.hide();
      } else {
        box.detailsBox.submitting.show();
        box.detailsBox.saved.hide();
      }
      box.detailsBox.show();
      if (box.bAutoSubmit) {
        toggleFieldsIn(box.uploadBox, false);
      }
      box.idField.value = box.idField.originalValue;
    }
  }

  var clickImage = function () {
    if (box.populatedSrc && box.bUploading) {
      box.image.src = box.populatedSrc;
      toggleUploadOrDetails(false, box.populatedSrc ? true : false);
    } else if (!box.bUploading) {
      box.image.src = '/images/generic/bg_blank_asset.gif';
      toggleUploadOrDetails(true);
    }
  }

  var changeWithAutoSubmit = function () {
    // Safari hack to prevent stalled uploads due to kept-alive connections.
    closeKeepAlive();

    Draftability.saveDraft(function (context) {
      var assetData = context.asset;
      box.idField.value = box.idField.originalValue = assetData.id;
      box.image.src = box.populatedSrc = assetData.src;
      var assetDetails = "<strong>" + assetData.name + "</strong><br />" +
        assetData.size + "kb " + assetData.asset_type + "<br />";
      if (assetData.asset_type == "image") {
        assetDetails += assetData.width + "x" + assetData.height + "pixels";
      }
      box.detailsBox.saved.update(assetDetails);
      toggleUploadOrDetails(false, true);
    });

    box.idField.value = '';

    box.fileField = resetField(box.fileField);
    monitorChanges();

    toggleUploadOrDetails(false, false);
    box.image.src = "/images/generic/spinner_asset.gif";
  }

  var changeWithoutAutoSubmit = function () {
    toggleUploadOrDetails(false, false);
    box.image.src = box.populatedSrc = '/images/generic/bg_pending_asset.gif';
  }

  var monitorChanges = function () {
    Event.observe(
      box.fileField,
      'change',
      box.bAutoSubmit ? changeWithAutoSubmit : changeWithoutAutoSubmit
    );
  }

  init();
}


function toggleAuthorship() {
  var authorId = $('authorId');
  var authorAvatar = $('authorAvatar');
  var authorName = $('authorName');
  var authorLogin = $('authorLogin');
  var authorToggle = $('authorToggle');

  var oldId = authorId.value;
  var oldAvatar = authorAvatar.src;
  var oldName = authorName.innerHTML;
  var oldLogin = authorLogin.innerHTML;
  var oldToggleText = authorToggle.innerHTML;
  var oldToggleClass = authorToggle.className;

  authorId.value = authorId.getAttribute('newId');
  authorAvatar.src = authorAvatar.getAttribute('newAvatar');
  authorName.update(authorName.getAttribute('newName'));
  authorLogin.update(authorLogin.getAttribute('newLogin'));
  authorToggle.update(authorToggle.getAttribute('newText'));
  authorToggle.className = authorToggle.getAttribute('newClass');

  authorId.setAttribute('newId', oldId);
  authorAvatar.setAttribute('newAvatar', oldAvatar);
  authorName.setAttribute('newName', oldName);
  authorLogin.setAttribute('newLogin', oldLogin);
  authorToggle.setAttribute('newText', oldToggleText);
  authorToggle.setAttribute('newClass', oldToggleClass);
}



/* Help tips */

function helpTip(evt) {
  elem = $(Event.element(evt));
  var text = elem.getAttribute('help_text');
  var tip = $(document.createElement('div'));
  tip.update(text);

  elem.parentNode.appendChild(tip);

  tip.className = 'fieldHelpTip';
  var offsets = elem.cumulativeOffset();
  tip.setStyle({
    position: 'absolute',
    left: (offsets['left'] + 3) + 'px',
    top: ((offsets['top'] + elem.offsetHeight) - (tip.offsetHeight + 3)) + 'px'
  });

  //Effect.Grow(tip, {direction: 'bottom-left', duration: 0.2});

  Event.stop(evt);

  tip.closeEvt = function (evt) {
    Event.stop(evt);
    Event.stopObserving(document, 'click', tip.closeEvt);
    tip.remove();
  }
  Event.observe(document, 'click', tip.closeEvt);
}

Event.observe(
  window,
  'load',
  function () {
    $$('.fieldHelp').each(function (elem) {
      elem.observe('click', helpTip);
    });
  }
);
