// create the handle on the items in order to drag them
function findHandle(item) {
	var children = item.getElementsByTagName("div");
    for (var i = 0; i < children.length; i++)
    {
        var child = children[i];
        if (!child.hasAttribute("class")) continue;
        if (child.getAttribute("class").indexOf("handle") >= 0)
            return child;
    }
	return null;
}



// Update the task list order after the drag was performed.
function dragEnd(item)
{
    var listItem = item.parentNode;
    var tasklistName = listItem.id;
    var items = listItem.getElementsByTagName("li");
	var itemString = "";
	for (var i = 0; i < items.length; i++) {
	    if (items[i].style.display != 'none')
	    {
		    itemString = itemString + "," + items[i].getAttribute("taskname");
        }
	}
	var form = document.getElementById(tasklistName+"MoveForm");
	form.taskNames.value = itemString;
    form.submit();
}

/**
  * The tasklist object provides add, remove and status functions.
  *
  */
function Tasklist( name )
{
    this.name = name + "";
    this.totalTasks = 0;
    this.completeTasks = 0;

    this.updateProgressBar = updateProgressBar;
    this.initDragFunction = initDragFunction;
    this.addTask = addTask;
    this.removeTask = removeTask;
    this.changeStatus = changeStatus;
    this.promptOnDelete = true;

    function updateProgressBar()
    {
        var progressBarElem = document.getElementById(this.name + "ProgressBar");
        var percentComplete =  Math.round(100 * this.completeTasks / this.totalTasks);
        var percentIncomplete = 100 - percentComplete;

		var cellArray = progressBarElem.getElementsByTagName("td");
		var greenBar = cellArray[0];
		var redBar = cellArray[1];

        greenBar.style.width=percentComplete + "%";
        redBar.style.width=percentIncomplete + "%";
    }

    function initDragFunction()
    {
        var browserName=navigator.appName;
	    DragSort.makeListSortable(document.getElementById(this.name));
	    var items = document.getElementById(this.name).getElementsByTagName("li");
    	for (var i = 0; i < items.length; i++) {
		    DragSort.makeItemSortable(items[i]);
            // due to problems with the handle under IE, we make the whole li object dragable when IE is detected.
            if (browserName != "Microsoft Internet Explorer")
	    	    items[i].setDragHandle(findHandle(items[i]));
            else
                items[i].style.cursor = "move";
	    }
    }

    /*
     * Paramemter:  uri (uri to the addTask action
     *              formName (for convinience. Could also be created based on the tasklist.name)
     * Function will send a server request, without updating the current content object.
     * The response will be the content for a new tasklist item which will be included in a new list object via elem.innerHTML.
     * The same method is used when a task status is updated. The current content will be deleted and the new data
     * including the name of the task completer and the current status icon are created on the server and substitute the old content.
     * This was easier to implement then manipulating all single objects via javascript.
     */
    function addTask(uri, formName)
    {
        var formElem = document.forms[formName];
        var listName = formElem.listName.value;
        uri = uri + "?task=" + encodeURIComponent(formElem.task.value);
        uri = uri + "&listName=" + encodeURIComponent(listName);
        uri = uri + "&entityId=" + encodeURIComponent(formElem.entityId.value);

        var scope = this;

        var opts =
        {
            onComplete: function(data) {
                if (data.responseText != "")
                {
                    var listElem = document.getElementById(listName);
                    var elem = document.createElement('li');
                    var taskElem = formElem.task;
                    elem.setAttribute("id", "alphaView");
                    elem.setAttribute("taskname", taskElem.value);
                    elem.setAttribute("status", "incomplete");
                    elem.setAttribute("class", "view");
                    elem.innerHTML = data.responseText;
                    listElem.appendChild(elem);

                    scope.totalTasks= scope.totalTasks + 1;
                    scope.updateProgressBar();

                    scope.initDragFunction();

                    // clear form field
                    formElem.task.value = "";
                }
                else
                {
                    alert('An error occured trying to delete a task.\n\n'+ data.responseText);
                }
            }
        }

        // Send request to server...
        var req = new Ajax.Request(uri, opts);
        return false;
    }

    // Remove Task function sends a server request and if the result == success deletes the item.
    // Otherwise an error message will be displayed.
    function removeTask(uri, elem)
    {
      var scope = this;
      var DELETE_MSG = "Deleting this task is permanent.\n\nClick 'OK' to continue with delete.";
      if (!scope.promptOnDelete || confirm(DELETE_MSG))
      {
         var dom = $(elem);
         var opts = {
            onComplete: function(data) {
               if (data.responseText == "success")
               {
                  if (elem.getAttribute('status') == 'complete')
                  {
                    scope.completeTasks = scope.completeTasks - 1;
                  }
                  scope.totalTasks= scope.totalTasks - 1;
                  scope.updateProgressBar();
                  Element.removeClassName(dom, 'loading');

                  // This is where an Effect would be really cool!
                  new Effect.Fade(dom);
               }
               else
               {
                  Element.removeClassName(dom, 'loading');
                  alert('An error occured trying to delete a task.\n\n');
               }
            }
         }
         // turn on the loading animation...
         Element.addClassName(elem, 'loading');

         // Send request to server...
         var req = new Ajax.Request(uri, opts);
      }
      return false;
    }

    // Remove Task function sends a server request and if the result == success delete the item.
    // Otherwise display an error message.
    function changeStatus(uri, elem)
    {
        var dom = $(elem);
        var scope = this;
        var opts =
        {
            onComplete: function(data)
            {
                if (data.responseText != "error")
                {
                    if (elem.getAttribute('status') == 'complete')
                    {
                        elem.setAttribute('status', 'incomplete');
                        scope.completeTasks = scope.completeTasks - 1;
                    }
                    else
                    {
                        elem.setAttribute('status', 'complete');
                        scope.completeTasks = scope.completeTasks + 1;
                    }
                    scope.updateProgressBar();

                    elem.innerHTML = data.responseText;
                    scope.initDragFunction();
                    Element.removeClassName(dom, 'loading');
                }
                else
                {
                    Element.removeClassName(dom, 'loading');
                    alert('An error occured during task update.\n\nThe task might have been removed by another user.');
                }
            }
        }
        // turn on the loading animation...
          Element.addClassName(elem, 'loading');

        // Send request to server...
        var req = new Ajax.Request(uri, opts);
        return false;
    }
}
