function faceInit() {
//  setupAjaxLinks();
  setupEditors();
  setupAnonLink();
  setupEditToggles();
  setupDeleteItems();
  setupToggleVisibility();
  setupEditableRows();
  setupAnonNameTyper();
  setupSortLists();
  processLocationHash();
  // setup fading messages
  var now = new Date();
  var messages = $$('.fadeaway');
  messages.each(function(m) {
    new GoAway(m, 5);
  });
}

function setupEditors() {
  var editables = $$('.editable');
  editables.each(function(element) {
    new Ajax.InPlaceEditor(element, '/seattle/Face/AjaxHelper',
      { rows:10, cols:50, cancelControl:'button', okText:'Save Changes', cancelText:'Cancel', hoverClassName:'hovered', externalControl:'editButton:Comment',
      onComplete:function(transport,editor) {
        if (transport && editor) updateEditedComment(transport,editor);
      }
    }); 
  });
}
function updateEditedComment(transport,editor) {
  var editedComment = transport.responseText;    
  var targets = $$('.target_'+editor.id.split('editor:')[1]);
  targets.each(function(field) {
    field.value = editedComment;
  });
}

function setupEditableRows(rowID) {
  if(rowID) {
    var row = $(rowID);
    var controls = $(row.id+'-Controls');
    if(!row.hasClassName('hasEditable') && controls) {
      Event.observe(row,'mouseover', function(c){controls.show();});
      Event.observe(row,'mouseout', function(c){controls.hide();});
      row.addClassName('hasEditable');
    }
  } else {
    var rows = $$('.editableRow');
    rows.each(function(row) {
      var controls = $(row.id+'-Controls');
      if(!row.hasClassName('hasEditable') && controls) {
        Event.observe(row,'mouseover', function(c){controls.show();});
        Event.observe(row,'mouseout', function(c){controls.hide();});
        row.addClassName('hasEditable');
      }
    });
  }
}

function setupAjaxLinks(targetGroup) {
  if(targetGroup) { // maybe we only need to activate links for a single target, not the whole page. <script>setupAjaxLinks('myTargetDiv');</script>
    if($$('.target-'+targetGroup)) {
      var ajaxLinks = $$('.target-'+targetGroup);
    } else {
      var ajaxLinks = $$('.replace-'+targetGroup);
    }
  } else {
    var ajaxLinks = $$('.ajaxLink');
  }
  ajaxLinks.each(function(link) {
    if(!link.hasClassName('hasAjax')) { // We don't want to pile observers onto stuff that's already being observed.
      link.addClassName('hasAjax');
      Event.observe(link,'click', function(loader) {
        groupName = link.classNames().find(function(cls) {
          return cls.match(/^target-|^replace-/);
        });
        $$('.'+groupName).each(function(noncurrent) {
          noncurrent.removeClassName('current');
        });
        link.addClassName('current');
        
        params = link.href.toQueryParams();
        componentID = params.show;
        newHash = Object.toQueryString(params);
        
        if(groupName.startsWith('target-')) {
          params.loadType = 'update';
          target = groupName.gsub('target-','');
        } else {
          params.loadType = 'replace';
          target = groupName.gsub('replace-','');
        }
        loadComponent(componentID,target,params);
        if (newHash != null && !params.task) window.location.hash = newHash;
        loader.stop();
      });
    }
  });
}

function reloadComponent(target) {
  // check to see if there are show=componentIDs in the location hash that need to be loaded.
  var urlHash = window.location.hash.substring(1).toQueryParams();
  if(urlHash.show){
    if(!target){target = urlHash.target}
    if($(target) && !$(urlHash.show)) {
      if (urlHash.show && target) {
        //loadComponent(urlHash.show, target);
        loadComponent(urlHash.show, target)
      }
      links = $$('.target-'+target);
      links.each(function(link){
        if(link.id.endsWith(urlHash.show+'Link')) {
          link.addClassName('current');
        } else {
          link.removeClassName('current');
        }
      });
    }
  }
}

function forceAjaxLinks(div,target,component) {
  // Sometimes we can't edit the component, so we have to force the ajaxLinks.
  // An example would be foundation's pagination component.
  // I suspect this will fail if the anchors fall within other elements inside the div passed here.
  if($(div)) {
    $(div).childElements().each(function(a) {
      if(a.href) {
        a.addClassName('ajaxLink');
        a.addClassName('target-'+target);
        //a.href = a.href.gsub(/\&page=\d+|\?page=\d+/,'');
        if(!a.href.match(/show=/) && component) {
          if(!a.href.match(/\?/)) {
            a.href += "?show="+component;
          } else {
            a.href += "&show="+component;
          }
        }
      }
    });
  }
}

function processLocationHash() {
  var urlHash = window.location.hash.substring(1).toQueryParams();
  if (urlHash.show && urlHash.target) {
    // loadComponent(urlHash.showbig, urlHash.target);
  }
}
function submitAjaxForm(formID,targetID,params) {
  var timestamp = new Date().getTime();
  form = $(formID); target = $(targetID); values = form.serialize(true);
  if(params){values.update(params);} else {params = values;}
  params.ajax = true; params.method='GET';
  if(params && params.message) {
    message = $(params.message);
  } else if(!$(targetID+'-StatusMessage')) {
    target.insert({top:'<div id="'+targetID+'-StatusMessage" class="statusMessage" onclick="this.hide();"></div>'});
    message = $(targetID+'-StatusMessage');
  }
  //--------------------------------------------------------------------------
  if(params && params.task) {
    uriHash = $H({ task:params.task });
  } else if(params && params.show) {
    uriHash = $H({ show:params.show });
  } else {
    uriHash = $H({ cb:timestamp, ajax:'true' });
  }
  poundHash = $H(window.location.search.substring(1).toQueryParams());
  querystringHash = $H(window.location.hash.substring(1).toQueryParams());
  if(poundHash){uriHash.update(poundHash);}
  if(querystringHash){uriHash.update(querystringHash);}
  uriHash.update({ cb:timestamp, ajax:'true' });
  if(params){uriHash.update(params);}
  uri = '?'+uriHash.toQueryString();
  //--------------------------------------------------------------------------
  var myLoader = new ajaxObject(uri,targetID,params);
  myLoader.doUpdate();
}

function delRow(formID,rowID) {
  row = $(rowID);rowMessage = $(rowID+'-StatusMessage');deletedRow = $(rowID+'-Deleted');deletedRowMessage = $(rowID+'-Deleted-StatusMessage');
  if(row) {
    row.hide();
    if(!deletedRow) {row.insert({after:'<div id="'+rowID+'-Deleted" class="row deletedRow" style="display:none;"></div>'});}
    rowMessage.update('');deletedRowMessage.update('');deletedRow.show();
    submitAjaxForm(formID,rowID+'-Deleted');
  }
  return false;
}
function undoDelRow(rowID) {
  row = $(rowID);rowMessage = $(rowID+'-StatusMessage');deletedRow = $(rowID+'-Deleted');deletedRowMessage = $(rowID+'-Deleted-StatusMessage');
  if(row) {
    var formID = $(rowID+'-UndoDeleteForm');
    rowMessage.update('');deletedRowMessage.update('');
    deletedRow.hide();
    row.show();rowMessage.show();
    submitAjaxForm(formID,rowID);
  }
  return false;
}

function setupEditToggles() {
  var toggleLinks = $$('.editProfileLink');
  toggleLinks.each(function(tl) {
    Event.observe(tl, 'click', function(e) {
      var formid = 'f_'+tl.id.split(/l\d*_/)[1];
      if ($(formid)) {
        if (tl.innerHTML == 'edit') {
          new Effect.BlindDown($(formid), { duration:.15 });
          tl.innerHTML = 'hide';
        } else if (tl.innerHTML == 'hide') {
          new Effect.BlindUp($(formid), { duration:.15 });
          tl.innerHTML = 'edit';
        } else {
          $(formid).toggle();
        }
        tl.blur();
        Event.stop(e);
      }
    });
  });
}
function setupAnonLink() {
  $$('.anonPostToggleLink').each(function(lk) { 
    lk.observe('click', function(e) { 
      var queue2 = ($('createAccountForm').visible()) ? 'end' : 'front';
      new Effect.toggle('createAccountForm', family='blind', {duration:.5, queue: 'end'});
      new Effect.toggle('anonPostForm', family='blind', {duration:.5, queue: queue2});
      e.stop(); 
    });
  });
}
function setupDeleteItems() {
  var delLinks = $$('.delCollectionItem');
  delLinks.each(function(dl) {
    Event.observe(dl, 'click', function(e) {
      var conf = confirm('Are you sure you want to delete this? There is no undo.');
      if (conf) {
        var deleteID = dl.getAttribute('href').split('oid=')[1];
        var url = '/seattle/Face/FaceResponders';
        var processing = function() {
          dl.replace('<img src="/images/loading/spinner-blue-trans.gif" alt="loading..." />');
        };
        var success = function(transport) {
          var result = transport.responseText.evalJSON();
          if (result['success']) {
            new Effect.Fade('myItem_'+deleteID);
          } else {
            //console.log('errors: '+result['error']);
          }
        };
        new Ajax.Request(url, {
          method: 'post',
          parameters: { oid : deleteID, ajax : 'deleteitem' },
          onCreate: processing,
          onSuccess: success
        });
      }
      dl.blur();
      Event.stop(e);
    });
  });
}
function setupToggleVisibility() {
  var visLinks = $$('.itemVis');
  visLinks.each(function(vl) {
    Event.observe(vl, 'click', function(e) {
      var itemID = vl.id.split('itemVis')[1];
      var url = '/seattle/Face/FaceResponders';
      var processing = function() {
        vl.toggleClassName('loading');
      };
      var success = function(transport) {
        var result = transport.responseText.evalJSON();
        if (result['success']) {
          vl.toggleClassName('loading');
          if (vl.hasClassName('visPublic')) {
            vl.removeClassName('visPublic');
            vl.addClassName('visPrivate');
            vl.setAttribute('title', 'This item is private. Click to change.');
          } else if (vl.hasClassName('visPrivate')) {
            vl.removeClassName('visPrivate');
            vl.addClassName('visPublic');
            vl.setAttribute('title', 'This item is public. Click to change.');
          }
        }
      };
      new Ajax.Request(url, {
        method: 'post',
        parameters: { oid : itemID, ajax : 'switchvis' },
        onCreate: processing,
        onSuccess: success
      });
      vl.blur();
      Event.stop(e);
    });
  });
}
function setupAnonNameTyper() {
  if ($('anonOnlyPostForm') && $('anonScreenName')) {
    $('anonScreenName').observe('keyup',function() {
      if ($F('anonScreenName') == '') {
        $('commentAuthorByline').innerHTML = 'Your Name Here';
      } else {
        $('commentAuthorByline').innerHTML = $F('anonScreenName');
      }
    });
  }
}
function setupSortLists() {
  var sortables = $$('.dragSortList');
  if (sortables.length > 0) {
    sortables.each(function(d) {
      Sortable.create(d, {
        handle: 'drag_handle',
        onUpdate: function(list) {
          var params = {"sortThese": Sortable.sequence(list), "ajax": "sortlinks" };
          var url = '/seattle/Face/FaceResponders';
          new Ajax.Request(url, {
            parameters: params,
            method: 'get',
            onSuccess: function(transport) {
              var result = transport.responseText.evalJSON();
              if (result['success']) {
                list.highlight({ startcolor: '#99ff99' });
              } else {
                //console.log('errors: '+result['error']);
              }
            }  
          });
        }
      });
    });
  }
}

/* Character counter thanks to http://blog.ninedays.org */
function charCounter(id, maxlimit, limited){
  if (!$('counter-'+id)){
    //$(id).insert({after: '<div id="counter-'+id+'"></div>'});
    document.write('<span id="counter-'+id+'"></span>');
  }
  if($F(id).length >= maxlimit){
    if(limited){  $(id).value = $F(id).substring(0, maxlimit); }
    $('counter-'+id).addClassName('charcount-limit');
    $('counter-'+id).removeClassName('charcount-safe');
  } else {  
    $('counter-'+id).removeClassName('charcount-limit');
    $('counter-'+id).addClassName('charcount-safe');
  }
  $('counter-'+id).update( $F(id).length + '/' + maxlimit );  
}

function makeItCount(id, maxsize, limited){
  if(limited == null) limited = true;
  if ($(id)){
    Event.observe($(id), 'focus', function(){charCounter(id, maxsize, limited);}, false);
    Event.observe($(id), 'keyup', function(){charCounter(id, maxsize, limited);}, false);
    Event.observe($(id), 'keydown', function(){charCounter(id, maxsize, limited);}, false);
    charCounter(id,maxsize,limited);
  }
}
addLoadEvent(faceInit);