// KEEP IT SHORT

// Togglers - mark something "toggler" and automatically get it to appear/disappear
// mark an a href with class="toggler", id="blah" and the box it controls id="blah-box"
// the box should be display: none
var showRE = /(.*)(show )(.*)/;
var addRE = /(.*)(add )(.*)/;
var hideRE = /(.*)hide (.*)/;
function SetTogglers(elem) {
  var whichBox = "#" + elem.id + "-box";
  var a;
  if (a = elem.innerHTML.match(showRE)) {
    elem.original_verb = a[2];
    elem.innerHTML = elem.innerHTML.replace(showRE, '$1'+"hide "+'$3')
  } else if (a = elem.innerHTML.match(addRE)) {
    elem.original_verb = a[2];
    elem.innerHTML = elem.innerHTML.replace(addRE, '$1'+"hide "+'$3')
  } else {
    if ( elem.original_verb == undefined ) {
      elem.original_verb = "show "
    } 
    elem.innerHTML = elem.innerHTML.replace(hideRE, '$1'+elem.original_verb+'$2')
  }
  $(whichBox).slideToggle("slow");
}

// Initialization
$(document).ready(function() {
  $("a.toggler").click(function(){ SetTogglers(this) });
  // "new_window" will automatically tack on a target=_blank, in essence
  $("a.new_window").click(function(){
    window.open(this.href,"_blank");
    return false;
  });
});


// Cookie helpers
function SetCookie(name,value,days) {
if (days) var expires = "; expires="+((new Date()).setTime(date.getTime()+(days*24*60*60*1000)))
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}

// called upon click; swap out "this" (jquery; presumably an anchor) and 
// insert the html into the next DOM elem
function swapOut(me, html) {
  me.css("display", "none");
  span = me.next();
  span.html(html);
  return false; 
}

// flips all show-images remaining
function swapAllOut() {
  $(".show-image").trigger("click");
}

// The Previewer
function PreviewerPrototype() {
  // defaults
  this.previous_keystroke = new Date();
  this.last_keystroke = new Date();
  this.last_preview   = new Date();
  this.timer_delay    = 200;  // in msecs.
  this.keystroke_gap  = 2000; // in msecs.
  this.preview_gap    = 1000; // in msecs.
  // We must apply an ordering to the asynchronous calls; otherwise
  // an earlier call may usurp a later one
  this.version=1;
  this.best_version=0;
  this.started=false;
}

//body, preview_div, form are jQuery selectors
function Previewer(body,preview_div,url,form){
  this.body=body;
  this.preview_div=preview_div;
  this.form=form;
  this.url=url;
  this.off_button=undefined;

  // don't call directly from something like onkeyup; use notify instead.
  // but call this directly if user action demands it; in which case NEVER call
  // notify
  this.doPreview = function(off_button) {
    var the_body = $(this.body).val()
    if (the_body.length == 0) {
      $(this.preview_div).empty()
      return;
    }

    if (the_body.length > 5000) {
      // TODO: better HTML
      $(this.preview_div).html("<div class='indent headroom'><i>Sorry, you may only preview short text.</i></div>");
      return;
    }

    if (off_button != undefined) {
      this.off_button = true;
    }

    var me = this;
    // jQuery apparently doesn't respect a checkbox's or radio button's state when 
    // dehydrating them.  Then, Rails stuffs the "off value" of checkboxes in 
    // a hidden. Gotta handle both real special - annoyingly
    var form_items = $(this.form + " :input").not(":radio");
    form_items = form_items.not(":checkbox"); // safari 2 doesn't like chaining calls
    var checkboxes = $("input:checkbox").map( function() { 
      if (!this.backup_value) { this.backup_value = this.value; } 
      var checkbox = this;
      form_items = form_items.filter(function() { 
        if ( checkbox.name == this.name ) {
          checkbox.value = checkbox.checked ? checkbox.backup_value : this.name;
          return 0==1;
        }
        return 1==1; });
      return this; 
    }).get();
    var radiobuttons = $("input:radio").filter(":checked");  

    // set the ajax event in motion
    $.ajax({
      type:"POST", url:this.url, 
      data: form_items.add("<input type='hidden' name='version' value='"+this.version+"'/>").add(checkboxes).add(radiobuttons),
      success: function(html) {
        if ( html.match(/version=([0-9]+)/) ) {
          var received_version = parseInt(RegExp.$1 || "0");
          if (received_version >= me.best_version) {
            $(me.preview_div).html(html);
            me.best_version = received_version;
            // this doesn't work in IE; the focus will return the cursor to the start of the text - sigh
            if (me.off_button != undefined) {
              window.location.href=me.preview_div; 
              $(me.body).focus(); // FF3b5 resets focus upon href change; so set it back 
            }
          }
        }
      }
    })

    this.version = this.version + 1;
  }
  
  this._periodic = function() {
    // if the keystrokes are not too close...
        // last event must be keystroke...
        // ... and there must not have been a preview recently
    if ((this.last_keystroke - this.previous_keystroke > this.keystroke_gap) && 
        (this.last_preview < this.last_keystroke) &&   
        (new Date() - this.last_preview > this.preview_gap)) {  
      this.doPreview();
      this.last_preview = new Date();
    }
  }

  this.notify = function(evt) {
    // make sure not to process non-input keys
    //arrow keys, page up/down, home, end
    if (evt!=undefined) {
      if ( evt.keyCode <= 40 && evt.keyCode >= 33) return;
      // F1-F12
      if ( evt.keyCode <= 123 && evt.keyCode >= 112) return;
      switch(evt.keyCode){
        case 16: // shift
        case 17: // ctrl
        case 18: // alt
        case 19: // pause/break
        case 20: // caps
        case 27: // escape
        case 44: // print screen
        case 45: // insert
        case 91: // meta
        case 92: // meta2
        case 144: // numlock
        case 145: // scrolllock
          return
      }
    }
    this.preview_keystroke = this.last_keystroke;
    this.last_keystroke = new Date();
    //$(this.preview_div).append(".");
    if (!this.started) {
      var me = this;
      this.intervalID = window.setInterval(function(){me._periodic()},this.timer_delay);
      $(document).unload( function(){window.clearInterval(me.intervalID)}); //clean up memory?
      this.started = true;
      //$(this.preview_div).ScrollTo('normal'); // doesn't work in jQuery 1.2
    }
  } //notify
}//Previewer

Previewer.prototype = new PreviewerPrototype();


// Resizing images

// This does the math and recomputes the size of the image according to
// the width of the window, then sets it
var original_height=null;
var original_width=null;
function resizeImage(imageID) {
  var width = 0; var height = 0;
  var img = $('#'+imageID);

  var maxWidth = $(window).width();
  // normalize the widths coming back 
  if ($.browser.opera || $.browser.mozilla) {
    maxWidth=maxWidth+5;
  }
  if ($.browser.msie) {
    maxWidth=maxWidth+8;
  }
  maxWidth=maxWidth-43;    // for the surrounding HTML

  // Are we going back to the original size?
  if ( original_height != null && original_width != null ) {
     img.width(original_width);
     img.height(original_height);
     original_width=null;
     original_height=null;
     return;
  }

  // do nothing if we fit already
  if (img.width() < maxWidth) {
     return;
  }

  original_height = img.height();
  original_width = img.width();
  var fact = maxWidth / img.width();
  height = Math.round(img.height() * fact);
  img.width(maxWidth);
  img.height(height);
}

// tacks on @username to text_area given
var tackOnHasRun = null;
function tackOn(username,text_area) {

  // if there's something there already, place it differently
  var to_add = "@" + username + ", ";

  $(text_area).val( $(text_area).val() + to_add );

  // if we've already run, then don't scroll down
  if ( !tackOnHasRun ) {
    window.location.href=text_area; 
    $(text_area).focus(); // FF3b5 resets focus upon href change; so set it back 
    //$(text_area).effect("highlight",{color:"#FF8533"},600);
    $(text_area).effect("highlight",{color:"#dddddd"},600);
  }

  tackOnHasRun = true;

  return false;
}

function markMessagesRead(textClass, textID, divToLoad) {
  textType = 'C';
  if (textClass == "TopicComment") { textType = 'TC'; }
  if (textClass == "Topic") { textType = 'T'; }

  $(divToLoad).load( "/account/mark_messages_seen", {text_id: textID, text_type: textType});
}
function markUnlocksRead(ID, divToLoad) {
  $(divToLoad).load( "/account/mark_unlocks_seen", {id: ID});
}

function addFavorite(me, id_code, receiver_id, parent_id) {
  $(me).load( "?", { add_favorite: id_code, receiver_id: receiver_id, parent_id: parent_id, ajax: 1 });
  return false;
}
function removeFavorite(me, id_code) {
  $(me).load( "?", { remove_favorite: id_code, ajax: 1 });
  return false;
}

function addUnfavorite(my_post, me, id_code, receiver_id, parent_id) {
  $(me).hide();

  $(my_post).addClass('scheduledForRemoval');

  $(my_post).prepend(
"<div class='unFavorite areYouSure'>Are you sure you want to close the post below?  \
If you close it, there's no easy way to come back to this. \
<br/> \
<br/> \
<a href='?' onclick=\"proceedWithUnfavorite('" +
  my_post + "', '" + me + "', '" + id_code + "', '" + receiver_id + "', '" + parent_id + "' \
); return false;\">close it</a> \
&nbsp; <a href='?' onclick=\"cancelUnfavorite('" +
  my_post + "', '" + me + "'); return false;\">cancel</a> \
</div>");
  return false;
}
function cancelUnfavorite(my_post, me) {
  $(me).show();
  $(my_post + " .areYouSure").remove();
  $(my_post).removeClass('scheduledForRemoval');
  return false;
}
function proceedWithUnfavorite(my_post, me, id_code, receiver_id, parent_id)  {
  $(my_post).load( "?", { add_unfavorite: id_code, receiver_id: receiver_id, parent_id: parent_id, ajax: 1 });
  return false;
}

