/**
 * forum_control.js
 * Description: ForumControl class for LernOCP
 * Author: John Hughes
 * Date: 08/03/2008
 */

ForumControl = Class.create();
ForumControl.prototype = {
  m_items: null,

  initialize: function(o) {
    this.m_options = {
      open_image: '/Image/nav_open.gif',
      close_image: '/Image/nav_close.gif',
      controller: '/Controller/DiscussionController.cfc',
      message_form_method: 'remoteGetRenderedEditMessageForm',
      message_edit_method: 'remoteEditMessage',
      message_delete_method: 'remoteDeleteMessage',
	  message_move_form_method: 'remoteGetRenderedMoveMessageForm',
	  message_move_method: 'remoteMoveMessage',
      thread_id: null,
      render_threaded: false,
      sort_ascending: false
    };
    Object.extend(this.m_options, o || {});
    
    this.m_items = new Hash();
  },
  
  onActionStart: function() { WaitControl.busy(); },
  onActionEnd: function() { WaitControl.ready(); },
  
  /**
   * Toggles the open/close visual state of a message in the message-subject tree
   * @param MessageID {integer} the ID of the message
   */
  toggleTreeMessage: function(MessageID) {
    message = $('message-tree-' + MessageID);
    toggle_input = $('message-tree-toggle-' + MessageID);
    if(message) {
      child_ul = message.getElementsBySelector('ul')[0];
      if(child_ul)
        if(child_ul.visible()) {
          Effect.BlindUp(child_ul);
          toggle_input.src = this.m_options.open_image;
        } else {
          Effect.BlindDown(child_ul);
          toggle_input.src = this.m_options.close_image;
        }
    } else
      alert('MessageID ' + MessageID + ' couldn\'t be found in the DOM!');
  },
  
  /**
   * Collapses all message trees specified (no animation)
   * @param messages {array} the message ids to collapse
   */
  collapseMessages: function(messages) {
    messages.each(function(m) {
      $('message-tree-' + m).getElementsBySelector('ul')[0].hide();
      $('message-tree-toggle-' + m).src = this.m_options.open_image;
    }.bind(this));
  },
  
  /**
   * Requests a rendered edit form for a reply message and inserts it into the
   * nested message tree in the appropriate place.
   * @param {integer} ParentMessageID The parent message to reply to
   */
  showMessageEditForm: function(ParentMessageID, MessageID) {
    if(!ParentMessageID) ParentMessageID = 0;
    if(!MessageID) MessageID = 0;
    // Check if we're already showing the edit form..
    if((ParentMessageID && $('message-reply-item-' + ParentMessageID))
        || (MessageID && $('message-edit-item-' + MessageID))) return;
	

    new Ajax.Request(
      this.m_options.controller, {
        method: 'post',
        parameters: $H({ method: this.m_options.message_form_method,
                         MessageID: MessageID,
                         ThreadID: this.m_options.thread_id,
                         ParentMessageID: ParentMessageID || 0}).toQueryString(),
        onCreate: this.onActionStart,
        onComplete: this.onActionEnd,
        onSuccess: function(transport) {
          response = transport.responseText.strip();
          
          if(MessageID) { // Edit request
            i = $$('li#message-body-item-' + MessageID + '>div.message-tree-body')[0];

            temp_div = $(document.createElement("div"));
            temp_div.innerHTML = response.stripScripts();
                       
            this.m_items[MessageID] = i.parentNode.replaceChild(temp_div.firstDescendant(), i);
            response.evalScripts();
          } else { // Check to see if a replies ul already exists for this message
            replies_list = ParentMessageID ? $('message-body-replies-' + ParentMessageID) : $$("div.message-bodies>ul")[0];

            if(!replies_list) { // Then Build it!
              replies_list = Builder.node("ul", {id: 'message-body-replies-' + ParentMessageID});
              $('message-body-item-' + ParentMessageID).appendChild(replies_list);
            }
  
            if( MessageID == 0 && ParentMessageID == 0 &! this.m_options.sort_ascending)
              new Insertion.Top(replies_list, response);
            else
              new Insertion.Bottom(replies_list, response);
              
            response.evalScripts();
            
            viewport_height = self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
            
            reply_item = $('message-reply-item-' + ParentMessageID);

            // Scroll the page smoothly to be aligned with the bottom of the edit form.
            new Effect.ScrollTo(reply_item, {offset: -(viewport_height - reply_item.getHeight() * 1.5)});
          }
		  
		  if($('no_message'))
		  {
			$('no_message').hide();  
		  }
          
          this.onEditReady();
        }.bind(this),
        onFailure: function(transport) {
          $('debug').innerHTML = transport.responseText.strip().replace(/\r|\n/g, '');
        }
      }
    );
  },
  
  showMessageMoveForm: function (MessageID)
  {
	new Ajax.Request(
	this.m_options.controller,{
		method: 'post',
		parameters: $H({method: this.m_options.message_move_form_method,
					   	MessageID: MessageID}).toQueryString(),
		onCreate: this.onActionStart,
		onComplete: this.onActionEnd,
		onSuccess: function(transport)
		{
			response = transport.responseText.strip();
            i = $$('li#message-body-item-' + MessageID + '>div.message-tree-body')[0];
			temp_div = $(document.createElement("div"));
			temp_div.innerHTML = response.stripScripts();
			this.m_items[MessageID] = i.parentNode.replaceChild(temp_div.firstDescendant(),i);
			response.evalScripts();
			this.onMoveReady();
		}.bind(this)
    });
  },
  
  setMoveReadyFunction: function(f){
	this.onMoveReady = f;  
  },
  
  setEditReadyFunction: function(f) {
  	this.onEditReady = f;
  },
  
  hideMessageEditForm: function(ParentMessageID, MessageID) {
    ed = tinyMCE.get('message.body-edit-' + (MessageID?MessageID:ParentMessageID));
    ed.remove();
    
    if(MessageID) { // Edit form
      edit_item = $('message-edit-item-' + MessageID);
      if(edit_item)
        edit_item.parentNode.replaceChild(this.m_items[MessageID], edit_item);
    } else { // Reply form
      reply_item = $('message-reply-item-' + ParentMessageID);
      if(reply_item) {
        //Effect.BlindUp(reply_item)
        reply_item.remove();
      }
    }
    
    return false;
  },
  
  hideMessageMoveForm: function(MessageID) {
   	
    if(MessageID) { // Edit form
      move_item = $('message-move-item-' + MessageID);
      if(move_item)
        move_item.parentNode.replaceChild(this.m_items[MessageID], move_item);
    } 
    
    return false;
  },
  
  updateSubjectItem: function(MessageID, ParentMessageID, content) {
    if($$('div.message-tree').length==0) return;

    existing = $('message-tree-' + MessageID);
    if(existing) {
      existing.replace(content.unescapeHTML());
    } else { // New reply item.
      if(ParentMessageID) {
        parent_replies = $('message-tree-' + ParentMessageID).getElementsBySelector('ul')[0];
        if(!parent_replies) { // Build it!
          parent_replies = Builder.node("ul");
          $('message-tree-' + ParentMessageID).appendChild(parent_replies);
        }
        
        new Insertion.Bottom(parent_replies, content.unescapeHTML());
      } else {
        parent_replies = $$('div.message-tree>ul')[0];
        
        if(this.m_options.sort_ascending)
          new Insertion.Bottom(parent_replies, content.unescapeHTML());
        else
          new Insertion.Top(parent_replies, content.unescapeHTML());
      }
    }
  },
  
  /** Submit the previously-shown edit form via a hidden Iframe so that upload is possible. Updates the edit-pane
   * with the response from the controller.
   * @param {String} list_name The name of the list whos edit form to submit
   * @see #showListRecordEditForm
   */
  submitMessageEditForm: function(ParentMessageID, MessageID) {
  	if(!ParentMessageID) ParentMessageID = 0;
    if(!MessageID) MessageID = 0;
    
    this.onActionStart();
    
    // Ensure tinymce saves all editor content back to the form variables.
    //tinyMCE.triggerSave();
    ed = tinyMCE.get('message.body-edit-' + (MessageID?MessageID:ParentMessageID))
    ed.save();
    
    if(MessageID)
      message_item = $('message-edit-item-' + MessageID);
    else if(ParentMessageID)
      message_item = $('message-reply-item-' + ParentMessageID);
    else message_item = $('message-reply-item-0');

    form = message_item.getElementsBySelector('form')[0];
    
    // Build the iframe
    id = 'frame' + Math.floor(Math.random() * 10000);
    frame = Builder.node('iframe', {style: 'display: none;', src: 'about:blank', id: id, name: id});
    
    // For the form to find the frame as target, it actually needs to be in the DOM
    document.body.appendChild(frame);
    
    // Observe the frame load event.
    Event.observe(frame, 'load', this.submitFrameLoad.bindAsEventListener(this));
    
    var control = this.m_options.controller;
    var params = $H({method: this.m_options.message_edit_method, renderThreaded: this.m_options.render_threaded}).toQueryString();

    form.setAttribute('action', control + "?" + params);
    form.setAttribute('target', id);
    
    this.onEditReady = null;
    
    return true; // So the form can submit
  },
  
  submitMessageMoveForm:function(MessageID,NewParentID)
  {
	this.onActionStart();
	
	message_item = $('message-move-item-' + MessageID);
	form = message_item.getElementsBySelector('form')[0];
	

	var control = this.m_options.controller;
	
	var params = $H({method: this.m_options.message_move_method,MessageID:MessageID,ThreadID:NewParentID}).toQueryString();
	form.setAttribute('action',control + "?" + params);

	this.onMoveReady = null;
	return true;
	
  },
  
  /**
   * Message handler called when a hidden iframe loads result back from controller.
   */
  submitFrameLoad: function(e) {
  	frame = Event.element(e);
  	if(!frame)
      frame = e.currentTarget;
  	
    if (frame.contentDocument)
      var doc = frame.contentDocument;
    else if (frame.contentWindow)
    	var doc = frame.contentWindow.document;
    else
    	var doc = window.frames[frame.id].document;

    if(doc.XMLDocument)
      response = doc.XMLDocument.xml;
    else
      response = doc.body.innerHTML;
    
    temp_div = $(document.createElement("div"));
    temp_div.innerHTML = response.stripScripts();
          
    ed.remove();
                       
    message_item.parentNode.replaceChild(temp_div.firstDescendant(), message_item);
    
    response.evalScripts();
    
    if(this.onEditReady)
      this.onEditReady();
      
    this.onActionEnd();
  },
  
  /**
   * Submit the previously-shown edit form via AJAX. Updates the edit-pane
   * with the response from the controller.
   * @param {String} list_name The name of the list whos edit form to submit
   * @see #showListRecordEditForm
   */
/*
  submitMessageEditForm: function(ParentMessageID, MessageID) {
    if(!ParentMessageID) ParentMessageID = 0;
    if(!MessageID) MessageID = 0;

    // Ensure tinymce saves all editor content back to the form variables.
    //tinyMCE.triggerSave();
    ed = tinyMCE.get('message.body-edit-' + (MessageID?MessageID:ParentMessageID))
    ed.save();
    
    if(MessageID)
      message_item = $('message-edit-item-' + MessageID);
    else if(ParentMessageID)
      message_item = $('message-reply-item-' + ParentMessageID);
    else message_item = $('message-reply-item-0');

    form = message_item.getElementsBySelector('form')[0];
    
    formHash = $H(Form.serialize(form, true));

    new Ajax.Request(
      this.m_options.controller, {
        method: 'post',
        parameters: formHash.merge({method: this.m_options.message_edit_method, renderThreaded: this.m_options.render_threaded}).toQueryString(),
        onCreate: this.onActionStart,
        onComplete: this.onActionEnd,
        onSuccess: function(transport) {
          response = transport.responseText.strip();
          
          temp_div = $(document.createElement("div"));
          temp_div.innerHTML = response.stripScripts();
          
          ed.remove();
                       
          message_item.parentNode.replaceChild(temp_div.firstDescendant(), message_item);
          response.evalScripts();
            
          //message_item.replace(response);
        }.bind(this),
        onFailure: function(transport) {
          $('debug').innerHTML = transport.responseText.strip().replace(/\r|\n/g, '');
        }
      }
    );

    return false; // So we don't actually post the form.
  },
*/
  
  /**
   * Deletes message tree with confirm message.
   * @param MessageID the message to delete.
   */
  deleteMessage: function(MessageID) {
    if(confirm("Are you sure you want to delete this message? All replies will also be deleted!")) {
      new Ajax.Request(
        this.m_options.controller, {
          method: 'post',
          parameters: $H({method: this.m_options.message_delete_method, 'MessageID': MessageID}).toQueryString(),
          onCreate: this.onActionStart,
          onComplete: this.onActionEnd,
          onSuccess: function(transport) {
 		    var browserName = navigator.appName;
			if(browserName == "Microsoft Internet Explorer")
			{
				location.reload(true);
			}
			  
            transport.responseText.evalScripts();
            // We can assume that onSuccess means the delete actually went through.
            // If there was a security problem, it would have redirected.
            
            // Remove the summary item from DOM:
            message_tree_item = $('message-tree-' + MessageID);
            
            // If the message to delete is the only one in a reply UL, delete the UL too.
            // Make sure not to delete the root UL (message-bodies)!
            if(message_tree_item)
			{
              if(message_tree_item.siblings().length == 0 && message_tree_item.parentNode.parentNode.hasClassName("message-tree"))
                message_tree_item.parentNode.remove();
              else
                message_tree_item.remove();
			}
			
			
            // Now remove the body from DOM
            message_item = $('message-body-item-' + MessageID);
			
            // If the message to delete is the only one in a reply UL, delete the UL too.
            // Make sure not to delete the root UL (message-bodies)!
            if(message_item.siblings().length == 0 && message_item.parentNode.hasClassName("message-bodies"))
              message_item.parentNode.remove(); 
            else
              message_item.remove();
			  

          }
        }
      );
    }
  }
};