var rmxCurSel = null;
var commentButtons = $A(['commentButton', 'floatingCommentButton']);
var remixButtons = $A([]); //
var floatingButtons = $A(['floatingCommentButton']); //

function isNull(e) {return (e==undefined || e==null);}
function rmInnerText(e) {
  e.innerHTML.stripScripts().unescapeHTML().replace(/[\n\r\s]+/g, ' ');
}
function tagSearch(el,tag,fnName,abort) {
  if(!el) return null;
  var TAG = tag.toUpperCase();
  var ABORT = abort ? abort.toUpperCase() : undefined;
  if(el.tagName==TAG) return el;//check this node
  while(true) {
    el = el[fnName];
    if(!el) {
      break;
    } else if(el.tagName==TAG) {
      return el;
    } else if(abort && el.tagName==ABORT) {
      return null;
    }
  }
  return null;
}
function parentSearch(el,tag,abort) {
  return tagSearch(el,tag,'parentNode',abort);
}
function siblingSearch(el,tag,fwdFirst) {
  return tagSearch(el,tag,fwdFirst ? 'nextSibling' : 'previousSibling',undefined) ||
         tagSearch(el,tag,fwdFirst ? 'previousSibling' : 'nextSibling',undefined);
}

function spanPositionInP(span) {
  if(span.tagName != 'SPAN') {
    
    span = parentSearch($(span),'SPAN','DIV');
  } else {
    span = $(span);
  }
  if(!span) return 0;
  return parentSearch(span,'DIV','DIV').select('SPAN').indexOf(span) + 1; 
}

function getSelectionTextTopBottom(win) {
  var sel,range,start,end;
  var head,headPosition,headWordPosition,tail,tailPosition,tailWordPosition;
  try {
    if (win.getSelection) { 
      sel = win.getSelection();
      if(sel.rangeCount <= 0) {
        return null;
      } else {
        range = sel.getRangeAt(0);
      }
    } else if (document.selection) { 
      sel = (IE ? win.document : document).selection;
      //TODO:
    } else if (document.getSelection) { 
      sel = document.getSelection();
    }

    if((start = parentSearch(range.startContainer,'SPAN','DIV') ||
                siblingSearch(range.startContainer,'SPAN',true))) {
      head = parentSearch(start,'DIV','DIV');
      headPosition = pPositionInMainIdeaText(head);
      headWordPosition = spanPositionInP(start);
    }
    if((end = parentSearch(range.endContainer,'SPAN','DIV') ||
              siblingSearch(range.endContainer,'SPAN',false))) {
      tail = parentSearch(end,'DIV','DIV');
      tailPosition = pPositionInMainIdeaText(tail);
      tailWordPosition = spanPositionInP(end);
    }

    //
    //
    var main = $$('#mainIdea .mainPoint').last();
    var headInsideMain = (head==main)||(head && head.descendantOf(main));
    var tailInsideMain = (tail==main)||(tail && tail.descendantOf(main));
    if( headInsideMain || tailInsideMain ) {
      var kidPs = main.select('DIV');
      if( !headInsideMain ) {
        head = kidPs.first();
        headPosition = 1; 
        start = head.down('SPAN');
        headWordPosition = 0; 
      }
      if( !tailInsideMain ) {
        tail = kidPs.last();
        tailPosition = kidPs.length; 
        var tailSpans = tail.select('SPAN');
        end = tailSpans.last();
        tailWordPosition = tailSpans.length; 
      }
    } else {
      head = headPosition = headWordPosition = null;
      tail = tailPosition = tailWordPosition = null;
    }

    if( head && tail ) {
      return {
        head: {p:head, position:headPosition, wordPosition:headWordPosition},
        tail: {p:tail, position:tailPosition, wordPosition:tailWordPosition},
        slurpText: (isNull(sel) ? 
          function() { 
            return $$('mainIdea .ideaP').collect(function(p) { return p.collectTextNodes() + "\n"; });
          } :
          function() { 
            var text='';
            eachFromToSiblingsOnly(head, tail,
              function(p) {
                var kids  = p.select('SPAN');
                var first = start.descendantOf(p) ? start : kids.first();
                var last  = end.descendantOf(p) ? end : kids.last();
                eachFromTo(first, last,
                  function(span) {
                    text += span.collectTextNodes();
                    if(span!=end) text += ' ';
                  });
                text += '\n\n';
              });
            return text;
          }).bind(this)
      };
    } else {
      return null;
    }
  } catch (e) {
    ;
  }
  return null;
}
function setBrowserSelection(win) {
  var sel, range;
  if (win.getSelection) { 
    sel = win.getSelection();
    try {
      if(sel && sel.rangeCount > 0) sel.collapseToStart();
    } catch(e) {
      
    }
  } else if (document.selection) { 
    sel = (IE ? win.document : document).selection;
    //TODO:
  } else if (document.getSelection) { 
    sel = document.getSelection();
  }
}
function clearBrowserSelection(win) {
  var sel, range;
  if (win.getSelection) { 
    sel = win.getSelection();
    try {
      if(sel && sel.rangeCount > 0) sel.collapseToStart();
    } catch(e) {
      
    }
  } else if (document.selection) { 
    sel = (IE ? win.document : document).selection;
    //TODO:
  } else if (document.getSelection) { 
    sel = document.getSelection();
  }
}
function clearSelection() {
  unHighlightSelectedText();
  if(rmxCurSel) {
    var head = rmxCurSel.head.p, tail = rmxCurSel.tail.p;
    if(head) head.removeClassName('selectedTop');
    if(tail) tail.removeClassName('selectedBottom');
    if(head && tail) {
      eachFromToSiblingsOnly
        (head,tail,function(s) {s.removeClassName('selectedMiddle');});
    }
  }
  floatingButtons.each( Element.hide );
  restoreMargins();
}
function prevInTree(e) {
  return e.previous() || e.up();
}  
function nextInTree(e) {
  var n = e.firstDescendant() || (e.next && e.next());
  while(!n && (e=(e.up && e.up()))) { 
    n = (e.next && e.next()); 
  }
  return n;
}
function eachFromToSiblingsOnly(head,tail,fn) {
  eachFromTo(head,tail,fn,function(e){return e.next();});
}
function eachFromTo(head,tail,fn,walker) {
  walker = walker || nextInTree;
  while(head && tail) {
    fn(head);
    head = (head==tail) ? null : walker(head);
  }
}
function blankMargins() {
  $$('.maskable').each(function(m){m.style.opacity=0.25;});
}
function restoreMargins() {
  $$('.maskable').each(function(m){m.style.opacity=1;});
}
function showButtonsAtTopAndBottom(onlyRemix) {
  if(!rmxCurSel) return;

  blankMargins();

  var headP = rmxCurSel.head.p;
  var tailP = rmxCurSel.tail.p;
  var headOffset = headP.positionedOffset();
  var tailOffset = tailP.positionedOffset();

    
  var commentB = $('floatingCommentButton');
  commentB.style.top = headOffset.top + 'px';
    // Math.max(headOffset.top, //no higher than this for short pghs
    //          headP.(headOffset.top + tailOffset.top + tailP.getHeight())/2 -
    //          commentB.getHeight()/2) + 'px';

    if( !onlyRemix ) commentB.show();
}
function doComment(ev) {
  hideCommentListsShowCounts();
  $('floatingCommentButton').hide();
  var fcb = $('floatingCommentBox');
  var top = (rmxCurSel && rmxCurSel.head)
    ? rmxCurSel.head.p.positionedOffset().top
    : ($('underMainText').positionedOffset().top - 60); 
  fcb.style.top = top + 'px';
  fcb.show();
  fcb.down('textarea').focus();
}
function moveShowAndScrollTo(e,to) {
  e.style.top = to + 'px';
  e.show();
}
function hideCommentWhenDone() {
  clearSelection();
  $('floatingCommentBox').hide();
  $$('#floatingCommentBox TEXTAREA').each(function(ta){ta.value = '';});
}
function cancelComment() {
  $('floatingCommentBox').hide();
  if(rmxCurSel) showButtonsAtTopAndBottom();
}

function pPositionInMainIdeaText(p) {
  var sibs=$$('.mainPoint .ideaP');
  return sibs.indexOf(p) + 1;
}


function updateFormForSubmit(prefix) {
  if( rmxCurSel && rmxCurSel.head ) {
    var head = rmxCurSel.head, tail = rmxCurSel.tail;
    $(prefix + "_quote").value = rmxCurSel.slurpText();
    $(prefix + "_head_position").value      = ''+head.position;
    $(prefix + "_head_word_position").value = ''+head.wordPosition;
    $(prefix + "_tail_position").value      = ''+tail.position;
    $(prefix + "_tail_word_position").value = ''+tail.wordPosition;
  }
}
function hideCommentListsShowCounts() {
  $$('.commentList').each(Element.hide);
  // $$('.commentCount').each(Element.show);
}
function showCommentList(offset,type,selected) {
  var cl = $(type+offset);
  var wasVisible = cl.visible();
  // $$('.commentCount').each(Element.hide);
  $$('.commentList').each(Element.hide);
  unHighlightSelectedText();
  cancelComment();
  clearSelection();
  cl.show();
  selectComment(type,offset,selected||0);
  blankMargins();

  rmxCurSel = null;
}
function hideCommentList(pghId) {
  restoreMargins();
  unselectAllComments();
  hideCommentListsShowCounts();
  $$('.mainHighlight').each(unHighlightMain);
}
function unselectAllComments() {
  unHighlightSelectedText();
  $$('.selected_suggestionComment, .selected_critiqueComment').each(function(c){
    c.removeClassName('selected_critiqueComment');
    c.removeClassName('selected_suggestionComment');
  });
}
var rmxsuggestionCoords = []; var rmxcritiqueCoords = [];
function selectComment(type,listOffset,commentOffset) {
  
  var co = this['rmx'+type+'Coords'][listOffset][commentOffset];
  unselectAllComments();
  highlightSelectedText($('ideaP'+co[0]),co[1],$('ideaP'+co[2]),co[3],type);
  $(type+listOffset+'-'+commentOffset).addClassName('selected_'+type+'Comment');
}
function handleCommentPostSuccess(resText) {
  clearCommentErrors();
  $('floatingCommentBox').hide();
  $('mainTextAndComments').update(resText);
  var msg = $('message');
  if(msg) {
    msg.relativize();
    msg.innerHTML = "Your comment was saved.";
  }
  hideCommentWhenDone();
}
function clearCommentErrors() {
  $('commentErrors').innerHTML = '';
}
function handleCommentPostFailure(resText) {
  clearCommentErrors();
  displayErrors(resText, 'commentErrors');
}
function highlightSelectedSpan(type,s) {
  s.addClassName(type ? 'selected_'+type+'Span' : 'selectedSpan');
}
function unHighlightSelectedText() {
  $$('.selectedSpan, .selected_critiqueSpan, .selected_suggestionSpan').each(function(s) {
    s.removeClassName('selectedSpan');
    s.removeClassName('selected_critiqueSpan');
    s.removeClassName('selected_suggestionSpan');
  });
}
function highlightSelectedText(head,headWord,tail,tailWord,type) {
  unHighlightSelectedText();
  clearBrowserSelection(window);
  eachFromToSiblingsOnly(head, tail, function(e) {
    var spans = e.select('SPAN');
    var from=0, to=spans.length-1;
    if((e == head) && headWord) from=Math.max(0,headWord-1);
    if((e == tail) && tailWord) to=Math.max(0,tailWord-1);
    eachFromTo(spans[from],spans[to], highlightSelectedSpan.curry(type));
  });
}


var emptyInquirer = 'pose a new question...';
function composeInquiry(ev) {
  $('inquirer').submit();
}
function focusInquirer(ev) {
  var el = $('inquirerQuestion');
  if(el.value == emptyInquirer) {
    el.value = '';
  }
  $('inquirer').addClassName('active');
  el.focus();
}
function blurInquirer() {
  var el = $('inquirerQuestion');
  if(el.value == '') {
    $('inquirer').removeClassName('active');
    el.value = emptyInquirer;
  }
}

/* */
function updateSelectionRedrawBoundingBox() {
  clearSelection();
  hideCommentListsShowCounts();
  rmxCurSel = getSelectionTextTopBottom(window);
  if( rmxCurSel && rmxCurSel.head && rmxCurSel.tail ) {
    var head = rmxCurSel.head.p, tail = rmxCurSel.tail.p;
    head.addClassName('selectedTop');
    tail.addClassName('selectedBottom');
    eachFromToSiblingsOnly(head,tail,function(s){ s.addClassName('selectedMiddle'); });

    var onlyShowRemixButton = false;
    var fcb = $('floatingCommentBox');
    if( fcb.visible() ) {
      moveShowAndScrollTo(fcb, head.positionedOffset().top);
      onlyShowRemixButton = true;
    }
    showButtonsAtTopAndBottom(onlyShowRemixButton);
    highlightSelectedText
      (rmxCurSel.head.p, rmxCurSel.head.wordPosition,
       rmxCurSel.tail.p, rmxCurSel.tail.wordPosition, null);
  }
  if(rmxUsername) doComment();
}
function highlightMain(e) {
  e.addClassName('mainHighlight');
}
function unHighlightMain(e) {
  e.removeClassName('mainHighlight');
}
function handleMouseup(ev) {
  setTimeout(function() {
    var main = $('mainTextAndComments');
    var clicked = ev.element();
    var curtain = $('curtain');
    if( clicked.match('.commentCount') ||
        floatingButtons.include(clicked.id) ||
        (curtain && clicked.descendantOf(curtain)) ||
        clicked.up('.popup') ||
        clicked.up('.commentList') ) {
      ;
    } else if( main == clicked || clicked.descendantOf(main) ) {
      setTimeout( 'updateSelectionRedrawBoundingBox()', 10 );
    } else if( rmxCurSel ) {
      
      var fcb = $('floatingCommentBox');
      if( (fcb.visible() && $F('idea_text')) || clicked.descendantOf(fcb) ||
          remixButtons.include(clicked.id) || commentButtons.include(clicked.id) ) {
        ;
      } else { 
        cancelComment();
        clearSelection();
        
        rmxCurSel = null;
      }
    } else { 
      hideCommentList();
    }
  }.bind(this), 10); 
  return true;
}
document.observe('dom:loaded', function() {
  $('mainIdea').cleanWhitespace(); 
  document.observe('mouseup', handleMouseup);
  $('floatingCommentButton').observe('click', fn_login_then_call(doComment, "Log in or sign up to add a comment"));
  var cb = $('commentButton');
  if(cb) {
    cb.observe('click', fn_login_then_call(function(ev) {
      if(!$('floatingCommentBox').visible()) { doComment(ev); }
    }));
  }
  var alt = $('alternativeButton');
  if(alt) {
    alt.observe('click', fn_login_then_call(function() {
      updateFormForSubmit('remix');
      var form = $('hiddenRemixForm');
      form.action = form.action.replace(/([^\/]|^)\/evolve/,'$1/answer');
      form.submit();
    }));
  }

  var e = $('editButton');
  if(e) e.observe('click', function() {
    updateFormForSubmit('remix');
    var form = $('hiddenRemixForm');
    form.action = form.action.replace(/([^\/]|^)\/evolve/,'$1/improve');
    form.submit();
  });
  
  var ib = $('inviteButton');
  if(ib) ib.observe('click', toggleInviteReaderForm);

  $$('#inquirer INPUT').each(function(tf) {
    if(tf.value != emptyInquirer) {
      tf.up().addClassName('active');
    }
    tf.observe('click', focusInquirer);
    tf.observe('blur', blurInquirer);
  });

    document.observe('keyup', catchKey.bindAsEventListener(this, Event.KEY_ESC, function() {
    if(rmxCurSel) {
      if($('floatingCommentBox').visible()) cancelComment();
      clearSelection();
    }
  })); 

    if(window.clipboardData) {
    var toClipboard = function(ev) {
      if(rmxCurSel) clipboardData.setData(rmxCurSel.slurpText());
    };
    $('mainIdea').observe('copy', toClipboard);
    $('mainIdea').observe('cut',  toClipboard);
  }                             
});

