var Form = {
	/*
  reset: function(form) {
    $(form).reset();
    return form;
  },
  */

  serializeElements: function(elements) {
    return elements.inject([], function(queryComponents, element) {
      var queryComponent = Form.Element.serialize(element);
      if (queryComponent) queryComponents.push(queryComponent);
      return queryComponents;
    }).join('&');
  }
};

Form.Methods = {
  serialize: function(form) {
    return Form.serializeElements($(form).getElements());
  },

  getElements: function(form) {
    return $A($(form).getElementsByTagName('*')).inject([],
      function(elements, child) {
        if (Form.Element.Serializers[child.tagName.toLowerCase()])
          elements.push(Element.extend(child));
        return elements;
      }
    );
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name)
      return inputs;

    var matchingInputs = new Array();
    for (var i = 0, length = inputs.length; i < length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) ||
          (name && input.name != name))
        continue;
      matchingInputs.push(Element.extend(input));
    }

    return matchingInputs;
  },

  disable: function(form) {
    form = $(form);
    form.set('disabled', true);
    return form;
  },

  enable: function(form) {
    form = $(form);
	form.set('disabled', false);
    return form;
  },

  findFirstElement: function(form) {
    return $(form).getElements().find(function(element) {
      return element.type != 'hidden' && !element.disabled &&
        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    form.findFirstElement().activate();
    return form;
  }
}

Object.extend(Form, Form.Methods);

var q = new Array();
function loginPostComment(username, password, postId, type) {
  Blog.login(username, password, function(b) {
    if (b) {
      postComment(postId, type);
    } else {
      alert((invalidLogin != null) ? invalidLogin : "Invalid username/password");
    }
  });
}
function loginSubmitForm(frm) {
  var frmName = frm.name;
  var username = frm.username.value;
  var password = frm.password.value;
  Blog.login(username, password, function(b) {
    if (b) {
      frm.submit();
    } else {
      Form.Methods.enable(frm);
      alert((invalidLogin != null) ? invalidLogin : "Invalid username/password");
    }
  });
}
function viewComments(postId, offset, type) {
  Blog.listPostComments(postId, offset, type, function(comments) {
    var id = "comments_" + postId;
    var pid = "post_" + postId;
    Util.setValue(id, comments);
    show(id);
    var dy = findPosY($(pid)) - findScrollY() - 50;
    slideBy(0, dy);
  });
}
function postComment(postId, type) {
  var frm = document.forms["replyForm_" + postId];
  var subject = frm.subject.value;
  var comment = frm.comment.value;
  Blog.postComment(postId, subject, comment, type, {
    preHook: function() { Form.Methods.disable(frm, true) },
    postHook: function() {
      Form.Methods.enable(frm);
      alert((postedComment != null) ? postedComment : "Your comment has been posted.");
    },
    callback: function(post) {
      var id = "post_" + postId;
      clearReply(postId);
      Util.setValue(id, post);
      var dy = findPosY($(id)) - findScrollY() - 50;
      slideBy(0, dy);
    }
  });
}
function viewPosts(catererId, type) {
  Blog.listPosts(catererId, type, function(posts) {
    var id = "all_posts";
    Util.setValue(id, posts);
  });
}
function clearReply(postId) {
    var frm = document.forms["replyForm_" + postId];
    frm.comment.value = "";
}
function hideReply(postId) {
    var pid = "post_" + postId;
    var id = "reply_" + postId;
    hide(id);
    var dy = findPosY($(pid)) - findScrollY() - 50;
    slideBy(0, dy);
}
function showReply(postId) {
    var id = "reply_" + postId;
    //var fn = "document.forms['replyForm_" + postId + "'].comment.focus()";
    show(id);
    //setTimeout(fn, "100");
    //clearTimeout();
    var dy = findPosY($(id)) - findScrollY() - 50;
    slideBy(0, dy);
}
function showEntry() {
    var id = "entry";
    //var fn = "document.userPostForm.subject.focus()";
    show(id);
    //setTimeout(fn, "100");
    //clearTimeout();
    var dy = findPosY($(id)) - findScrollY() - 50;
    slideBy(0, dy);
}
function hideComments(postId) {
    var id = "comments_" + postId;
    var pid = "post_" + postId;
    hide(id);
    var dy = findPosY($(pid)) - findScrollY() - 50;
    slideBy(0, dy);
}
function listComments(offset, type) {
  Blog.listComments(offset, type, function(comments) {
    var div = "comments";
    Util.setValue(div, comments);
    show(div);
    scrollTo(0, findPosY($(div)) - 50);
  });
  return false;
}
function listUserComments(userId, offset, type) {
  Blog.listUserComments(userId, offset, type, function(comments) {
    var div = "comments_" + userId;
    Util.setValue(div, comments);
    show(div);
    scrollTo(0, findPosY($(div)) - 50);
  });
  return false;
}
function showUserReply(postId) {
    var id = "reply";
    show(id);
    scrollTo(0, findPosY($(id)) - 50);
}
function show(id) {
    $(id).style.display = "";
}
function hide(id) {
    $(id).style.display = "none";
}
function isEmpty(s) {
    if (!s || s == "" || trim(s) == "") {
        return true;
    }
    return false;
}
function trim(s) {
    return s.replace( /^\s*/, "" ).replace( /\s*$/, "" );
}
function findScrollX() {
    return (document.all) ?
        (!document.documentElement.scrollLeft) ? document.body.scrollLeft : document.documentElement.scrollLeft
        : window.pageXOffset;
}
function findScrollY() {
    return (document.all) ?
        (!document.documentElement.scrollTop) ? document.body.scrollTop : document.documentElement.scrollTop
        : window.pageYOffset;
}
function findPosX(obj) {
    var curleft = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curleft += obj.offsetLeft
            obj = obj.offsetParent;
        }
    } else if (obj.x)
        curleft += obj.x;
    return curleft;
}
function findPosY(obj) {
    var curtop = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curtop += obj.offsetTop
            obj = obj.offsetParent;
        }
    } else if (obj.y)
        curtop += obj.y;
    return curtop;
}
function slideBy(x, y) {
    if (Math.abs(x) < 1 && Math.abs(y) < 1) {
        clearTimeout(q.shift());
        return;
    }
    var dx = x/2, dy = y/2;
    window.scrollBy(dx, dy);
    q.push(setTimeout("slideBy(" + dx + "," + dy + ")", 50));
}
if (typeof Form._disable == 'undefined') {
  Object.extend(Form, {
    _disable: Form.disable,
    disable: function(form, buttonOnly) {
      if (buttonOnly) {
        form = $(form);
        form.getElements().each(function(element) {
          var type = element.type.toLowerCase();
          if (type == 'submit' || type == 'reset' || type == 'button') {
            element.blur();
            element.disabled = 'true';
          }
        });
      } else {
        this._disable(form);
      }
      return form;
    }
  });
}

Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
}

Form.Element.Methods = {
  serialize: function(element) {
    element = $(element);
    if (element.disabled) return '';
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);

    if (parameter) {
      var key = encodeURIComponent(parameter[0]);
      if (key.length == 0) return;

      if (parameter[1].constructor != Array)
        parameter[1] = [parameter[1]];

      return parameter[1].map(function(value) {
        return key + '=' + encodeURIComponent(value);
      }).join('&');
    }
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);

    if (parameter)
      return parameter[1];
  },

  clear: function(element) {
    $(element).value = '';
    return element;
  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    element.focus();
    if (element.select)
      element.select();
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.blur();
    element.disabled = false;
    return element;
  }
}

function viewEventComments(postId, offset, type) {
  Blog.listEventPostComments(postId, offset, type, function(comments) {
    var id = "comments_" + postId;
    var pid = "post_" + postId;
    Util.setValue(id, comments);
    show(id);
    var dy = findPosY($(pid)) - findScrollY() - 50;
    slideBy(0, dy);
  });
}
function loginPostEventComment(username, password, postId, type) {
  Blog.login(username, password, function(b) {
    if (b) {
      postEventComment(postId, type);
    } else {
      alert((invalidLogin != null) ? invalidLogin : "Invalid username/password");
    }
  });
}
function postEventComment(postId, type) {
  var frm = document.forms["replyForm_" + postId];
  var subject = frm.subject.value;
  var comment = frm.comment.value;
  Blog.postEventComment(postId, subject, comment, type, {
    preHook: function() { Form.Methods.disable(frm, true) },
    postHook: function() {
      Form.Methods.enable(frm);
      alert((postedComment != null) ? postedComment : "Your comment has been posted.");
    },
    callback: function(post) {
      var id = "post_" + postId;
      clearReply(postId);
      Util.setValue(id, post);
      var dy = findPosY($(id)) - findScrollY() - 50;
      slideBy(0, dy);
    }
  });
}