var evalJSON = function (json) {
	try {
		return eval('(' + json + ')'); // temporary - TODO: add a real JSON parser
	} catch(e) {
		/* alert("Exception raised: " + e.description); */
		return undefined;
	}
};

var LuluGroup = function (iGroupID) {
	this.mGroupID = iGroupID;
};

LuluGroup.prototype.runGroupOp = function(iFinishedCallback, iOpName, iOpData, iURLBase) {
	var url = 'callbacks/' + iURLBase + '.php';
	var method = 'POST';
	var parameters = 'fOpName=' + iOpName + '&fGroupID=' + this.mGroupID;

	if(iOpData) {
		for(key in iOpData) {
			parameters = parameters.concat('&' + escape(key) + '=' + escape(iOpData[key]));
		}
	}

	var groupObject = this;

	var callback = {
		success: function (response) {
			if(response.status >= 300) {
				return iFinishedCallback(this, null);
			}

			var json = evalJSON(response.responseText);
			iFinishedCallback(this, json);
		},
		failure: function (response) {
			iFinishedCallback(this, null);
		},
		scope: groupObject
	}

	requestManager.makeRequest(url, method, parameters, callback);
};

LuluGroup.prototype.saveValue = function(iField, iValue, iFinishedCallback) {
	var params = {};
	params['FORM[' + iField + ']'] = iValue;

	return this.runGroupOp(iFinishedCallback, 'save', params, 'group_edit');
};

LuluGroup.prototype.addTag = function(iTagName, iFinishedCallback) {
	var params = {};
	params['FORM[tag_name]'] = iTagName;

	return this.runGroupOp(iFinishedCallback, 'add_tag', params, 'group_edit');
};

LuluGroup.prototype.removeTag = function(iTagID, iFinishedCallback) {
	var params = {};
	params['FORM[tag_id]'] = iTagID;

	return this.runGroupOp(iFinishedCallback, 'remove_tag', params, 'group_edit');
};

LuluGroup.prototype.removeMember = function(iAcctID, iFinishedCallback) {
	var params = {};
	params['fAcctID'] = iAcctID;

	return this.runGroupOp(iFinishedCallback, 'remove_member', params, 'group_member_edit');

};

LuluGroup.prototype.changeMemberRole = function(iAcctID, iNewRole, iFinishedCallback) {
	var params = {};
	params['fAcctID'] = iAcctID;
	params['fNewRole'] = iNewRole;

	return this.runGroupOp(iFinishedCallback, 'set_role', params, 'group_member_edit');
};

LuluGroup.prototype.approveSubmission = function(iWorkRequestID, iFinishedCallback) {
	var params = {};
	params['fWorkRequestID'] = iWorkRequestID;
	params['fMemberApproval'] = 'APPROVED';

	return this.runGroupOp(iFinishedCallback, 'approve_member', params, 'group_member_edit');
};

LuluGroup.prototype.denySubmission = function(iWorkRequestID, iFinishedCallback) {
	var params = {};
	params['fWorkRequestID'] = iWorkRequestID;
	params['fMemberApproval'] = 'DENIED';

	return this.runGroupOp(iFinishedCallback, 'deny_member', params, 'group_member_edit');
};

var LuluGroupPermissionSettingsDialog = function(iGroup) {
  this.mGroup = iGroup;
  this.setup();
};

LuluGroupPermissionSettingsDialog.prototype.handleSubmit = function() {
  this.hide();
  this.submit();
};

LuluGroupPermissionSettingsDialog.prototype.handleCancel = function() {
  this.hide();
  this.cancel();
};

LuluGroupPermissionSettingsDialog.prototype.handleSuccess = function(o) {
  var response = o;
  var json = evalJSON(o.responseText);
  if(!json || !json.ok) {
    alert((json && json.message)?json.message:'Save failed');
  }
};

LuluGroupPermissionSettingsDialog.prototype.handleFailure = function(o) {
  alert("Save failed: " + o.status);
};

LuluGroupPermissionSettingsDialog.prototype.handleLoadComplete = function(myDlg, jsonData) {
  /* Loads the stored data and stuffs it into the checkboxes before the user starts changing the settings */
  if(!jsonData || !jsonData.ok) {
    myDlg.mDialog.hide();
    alert((jsonData && jsonData.message)?jsonData.message:"Could not retrieve settings");
    return;
  }

  var selects = $DOM.getElementsByClassName('perms-settings-select', 'select', document.getElementById('perms-form'));
  jsonData.values.sort(function(a, b) { return a.operation.length - b.operation.length; });

  for(var i = 0; i < selects.length; i++) {
    var selectedItem = 'ALLOWED';

    var select = selects[i];

    var cbname = select.getAttribute('name');
    cbname = cbname.substr('FORM['.length);
    cbname = cbname.substr(0, cbname.length - 1);
    var operation = cbname;

    for(var j = 0; j < jsonData.values.length; j++) {
      if(jsonData.values[j].operation == operation) {
        selectedItem = jsonData.values[j].result;
        // alert("Selected " + selectedItem + " for " + operation);
      }
    }

    for(var j = 0; j < select.options.length; j++) {
      if(select.options[j].value == selectedItem) {
        select.selectedIndex = j;
        break;
      }
    }
  }

  this.mDialog.show();
};

LuluGroupPermissionSettingsDialog.prototype.loadSettings = function(ev, o) {
  var myDialog = this;

  var params = requestManager.makeParams({fOpName:'load_permission_settings',
                     fGroupID:myDialog.mGroup.mGroupID});

  var callback = {
    success : function (response) {
      if(response.status >= 300) {
        return myDialog.handleLoadComplete(myDialog, null);
      }

      var json = evalJSON(response.responseText);
      myDialog.handleLoadComplete(myDialog, json);
    },

    failure: function (response) {
      myDialog.handleLoadComplete(myDialog, null);
    },

    scope: myDialog
  };

  requestManager.makeRequest('callbacks/group_edit.php', 'POST', params, callback);
};

LuluGroupPermissionSettingsDialog.prototype.doShow = function() {
  if(! this.mDialog) {
    this.reallySetup();
  }

  this.loadSettings(); /* handleLoadComplete calls this.mDialog.show() */
};

LuluGroupPermissionSettingsDialog.prototype.reallySetup = function() {
  var lgnm = this;
  this.mDialog = new YAHOO.widget.Dialog("perms-dialog",
                 { width: "400px",
                     fixedcenter: true,
                   visible: false,
                   //draggable: true,
                     constraintoviewport: true,
                     buttons: [ { text:'Save Changes', handler:lgnm.handleSubmit, isDefault:true },
                    { text:'Cancel', handler:lgnm.handleCancel } ]

                     } );
  $DOM.setStyle('perms-dialog', 'display', 'block');
  // Wire up the success and failure handlers
  this.mDialog.callback = { success:lgnm.handleSuccess,
          failure:lgnm.handleFailure };

  this.mDialog.render();
}

LuluGroupPermissionSettingsDialog.prototype.setup = function() {
  YAHOO.util.Event.addListener("showPerms", "click", this.doShow, this, true);
};

var LuluGroupNotificationMessageDialog = function(iGroup) {
  this.mGroup = iGroup;
  this.mAudience = '';
  this.mEvent = '';
  this.mLangCode = 'EN';
  this.mDirty = false;

  this.setup();
};

LuluGroupNotificationMessageDialog.prototype.markMessageChanged = function(event) {
  this.mDirty = true;
};

LuluGroupNotificationMessageDialog.prototype.pullSettingsFromForm = function(event) {
  var me = this;

  var settingsFields = ['Event', 'Audience', 'LangCode'];

  for(var i = 0; i < settingsFields.length; i++) {
    var valelid = 'notemsg-f' + settingsFields[i];
    var valel = document.getElementById(valelid);
    var thisval;

    if(valel.nodeName == 'SELECT' || valel.nodeName == 'select') {
      thisval = valel.options[valel.selectedIndex].value;
    } else {
      thisval = valel.value;
    }

    this['m' + settingsFields[i]] = thisval;
  }
};

LuluGroupNotificationMessageDialog.prototype.updateMessage = function(event) {
  if(this.mDirty) {
    if(!confirm('You have not saved your changes to this message.\\nIf you choose a different message to edit, you will lose your changes.\\nDo you wish to continue?')) {
      return;
    }
  }

  this.pullSettingsFromForm();
  this.updateLanguage();
  this.loadMessageForSettings();
};

LuluGroupNotificationMessageDialog.prototype.updateLanguage = function() {
  var dispname = document.getElementById('notemsg-fLangCode-displayname');

  var langChooser = document.getElementById('notemsg-fLangCode');

  dispname.innerHTML = langChooser.options[langChooser.selectedIndex].innerHTML;
};

LuluGroupNotificationMessageDialog.prototype.handleShowMoreLanguages = function() {
  var disponly = document.getElementById('notemsg-fLangCode-displayonly');
  var langChooser = document.getElementById('notemsg-fLangCode');
  $DOM.setStyle(disponly, 'display', 'none');
  $DOM.setStyle(langChooser, 'display', 'inline');
};

LuluGroupNotificationMessageDialog.prototype.handleSubmit = function() {
  this.hide();
  this.submit();
  this.mDirty = false;
};

LuluGroupNotificationMessageDialog.prototype.handleCancel = function() {
  this.mDirty = false;
  this.hide();
  this.cancel();
};

LuluGroupNotificationMessageDialog.prototype.handleSuccess = function(o) {
  var response = o;
  var json = evalJSON(o.responseText);
  if(!json || !json.ok) {
    alert((json && json.message)?json.message:"Save failed");
  }
};

LuluGroupNotificationMessageDialog.prototype.handleFailure = function(o) {
  alert("Save failed: " + o.status);
};

LuluGroupNotificationMessageDialog.prototype.handleLoadComplete = function(myDlg, jsonData) {
  /* Loads the stored data and stuffs it into the checkboxes before the user starts changing the settings */
  if(!jsonData || !jsonData.ok) {
    myDlg.mDialog.hide();
    alert((jsonData && jsonData.message)?jsonData.message:"Could not retrieve settings");
    return;
  }

  var msgel = document.getElementById('notemsg-fMessage');
  if(jsonData.notification_message) {
    msgel.value = jsonData.notification_message;
  } else {
    msgel.value = '';
  }
  this.mDirty = false;
};

LuluGroupNotificationMessageDialog.prototype.loadMessageForSettings = function(o) {
  var myDialog = this;

  var params = requestManager.makeParams({fOpName:'load_notification_message',
                     fGroupID:myDialog.mGroup.mGroupID,
                     fAudience:myDialog.mAudience,
                     fEvent:myDialog.mEvent,
                     fLangCode:myDialog.mLangCode});

  var callback = {
    success : function (response) {
      if(response.status >= 300) {
        return myDialog.handleLoadComplete(myDialog, null);
      }

      var json = evalJSON(response.responseText);
      myDialog.handleLoadComplete(myDialog, json);
    },

    failure: function (response) {
      myDialog.handleLoadComplete(myDialog, null);
    },

    scope: myDialog
  };

  requestManager.makeRequest('callbacks/group_edit.php', 'POST', params, callback);
};

LuluGroupNotificationMessageDialog.prototype.doShow = function() {
  if(! this.mDialog) {
    this.reallySetup();
  }

  this.mDialog.show();
};

LuluGroupNotificationMessageDialog.prototype.reallySetup = function() {
  var lgnm = this;
  this.mDialog = new YAHOO.widget.Dialog("notemsg-dialog",
                 { width: "400px",
                     fixedcenter: true,
                     visible: false,
                     //draggable: true,
                     constraintoviewport: true,
                     buttons: [ { text:'Save Welcome Message', handler:lgnm.handleSubmit, isDefault:true },
                    { text:'Cancel', handler:lgnm.handleCancel } ]

                     } );
  $DOM.setStyle('notemsg-dialog', 'display', 'block');
  this.mDialog.beforeShowEvent.subscribe(lgnm.updateMessage, lgnm, true);

  // Wire up the success and failure handlers
  this.mDialog.callback = { success:lgnm.handleSuccess,
          failure:lgnm.handleFailure };

  this.mDialog.render();
}

LuluGroupNotificationMessageDialog.prototype.setup = function() {
  var lgnm = this;
  var noteRules = {
    "#notemsg-fMessage" : function(element) {
      YAHOO.util.Event.addListener(element, "change", lgnm.markMessageChanged, lgnm, true);
    },

    ".notemsg-selector" : function(element) {
      YAHOO.util.Event.addListener(element, "change", lgnm.updateMessage, lgnm, true);
    },

    "#notemsg-fLangCode-showmore" : function(element) {
      YAHOO.util.Event.addListener(element, "click", lgnm.handleShowMoreLanguages, lgnm, true);
    }
  };
  Behavior.register(noteRules);

  YAHOO.util.Event.addListener("showMsg", "click", this.doShow, this, true);
};

var LuluGroupFieldEditor = function(iGroup, iContentsID, iFieldName, iMenuItemID) {
  this.mGroup = iGroup;
  this.mFieldName = iFieldName;
  this.mDidSubmit = false;

  if(iContentsID) {
    this.mContents = $(iContentsID);
    this.mEditorID = iContentsID + '-editor';
    this.mSubmitID = iContentsID + '-submit';
    this.mCancelID = iContentsID + '-cancel';
    this.mMenuItemID = iMenuItemID;
    this.setupEditor();
  }
};

LuluGroupFieldEditor.prototype.processExistingValue = function(iExistingValue) {
  return iExistingValue;
}

LuluGroupFieldEditor.prototype.getInputWidth = function() {
  return 40;
}

LuluGroupFieldEditor.prototype.getInputHeight = function() {
  return 1;
}

LuluGroupFieldEditor.prototype.setupStartingValue = function() {
  if(this.mContents.innerText !== undefined) {
    existingValue = this.mContents.innerText;
  } else {
    existingValue = this.mContents.textContent;
  }

  this.mOldValue = this.mContents.innerHTML;

  var nrows = this.getInputHeight();

  if(nrows > 1) {
    this.mContents.innerHTML = '<textarea rows="' + nrows + '" cols="' + this.getInputWidth() + '" type="text" id="' + this.mEditorID + '">' + this.processExistingValue(existingValue) + '</textarea><br /><button class="smbutton" id="' + this.mSubmitID + '">Save</button>&nbsp;<button class="smbutton" id="' + this.mCancelID + '" />Cancel</button>';
  } else {
    this.mContents.innerHTML = '<input size="' + this.getInputWidth() + '" type="text" value="' + this.processExistingValue(existingValue) + '" id="' + this.mEditorID + '"/><button class="smbutton" id="' + this.mSubmitID + '" />Save</button>&nbsp;<button class="smbutton" id="' + this.mCancelID + '" />Cancel</button>';
  }
};

LuluGroupFieldEditor.prototype.setupEditor = function() {
  this.setupStartingValue();

  this.mEditor = document.getElementById(this.mEditorID);
  this.mSubmit = document.getElementById(this.mSubmitID);
  this.mCancel = document.getElementById(this.mCancelID);
  this.mEditor.focus();

  var gfe = this;
  this.mSubmit.onclick = 	function() {
    if(! gfe.mDidSubmit) {
      gfe.mDidSubmit = true;
      gfe.submitEditor();
    }
  };
  this.mCancel.onclick = 	function() {
    if(!gfe.mDidSubmit) {
      gfe.mDidSubmit = true;
      gfe.cancelEditor();
    }
  };
  this.mContents.onchange = this.mSubmit.onclick;

  var menuitem = $(this.mMenuItemID);
  if(menuitem) {
    this.mOldMenuItemDisplay = $DOM.getStyle(menuitem, 'display');
    $DOM.setStyle(menuitem, 'display', 'none');
  }

  if(! this.mGroup) {
    alert('mgroup empty in setupeditor');
  }
};

LuluGroupFieldEditor.prototype.getEditorValue = function() {
  return this.mEditor.value;
}

LuluGroupFieldEditor.prototype.postSaveFinished = function() {
  var menuitem = $(this.mMenuItemID);

  if(menuitem) {
    $DOM.setStyle(menuitem, 'display', this.mOldMenuItemDisplay);
  }
};

LuluGroupFieldEditor.prototype.submitEditor = function() {
  var gfe = this;
  this.mGroup.saveValue(this.mFieldName, this.getEditorValue(), function(grp, json) { gfe.saveFinished(grp, json); });
};

LuluGroupFieldEditor.prototype.cancelEditor = function() {
  this.mContents.innerHTML = this.mOldValue;
  this.postSaveFinished();
}

LuluGroupFieldEditor.prototype.saveFinished = function(iGroup, iJSON) {
  if(!iJSON.ok) {
    alert(iJSON.message);
  }

  newvalue = this.getEditorValue();
  this.mContents.innerHTML = newvalue;
  this.postSaveFinished();
};

var LuluGroupDescriptionEditor = function(iGroup, iContentsID, iFieldName, iMenuItemID) {
  LuluGroupFieldEditor.call(this, iGroup, iContentsID, iFieldName, iMenuItemID);
};

LuluGroupDescriptionEditor.prototype = new LuluGroupFieldEditor();

LuluGroupDescriptionEditor.prototype.getInputHeight = function() {
  return 3;
}

var LuluGroupURLEditor = function(iGroup, iContentsID, iFieldName, iMenuItemID) {
  LuluGroupFieldEditor.call(this, iGroup, iContentsID, iFieldName, iMenuItemID);
};

LuluGroupURLEditor.prototype = new LuluGroupFieldEditor();

LuluGroupURLEditor.prototype.processExistingValue = function(iExistingValue) {
  return existingValue.replace('http://www.lulu.com/groups/', '');
}

LuluGroupURLEditor.prototype.saveFinished = function(iGroup, iJSON) {
  this.mContents.innerHTML = '';

  if(!iJSON.ok) {
    alert(iJSON.message);

    // and restore the old value
  this.mContents.innerHTML = '<a href="http://www.lulu.com/groups/' + iJSON.oldSymbol + '">http://www.lulu.com/groups/' + iJSON.oldSymbol + '</a>';

    this.postSaveFinished();
    return;
  }

  var newSymbol = this.getEditorValue();
  this.mContents.innerHTML = '<a href="http://www.lulu.com/groups/' + newSymbol + '">http://www.lulu.com/groups/' + newSymbol + '</a>';

  this.postSaveFinished();
};

var LuluGroupInterestAdder = function(iGroup, iContentsID, iMenuItemID) {
  LuluGroupFieldEditor.call(this, iGroup, iContentsID, null, iMenuItemID);
};

LuluGroupInterestAdder.prototype = new LuluGroupFieldEditor();

LuluGroupInterestAdder.prototype.constructor = LuluGroupInterestAdder;

LuluGroupInterestAdder.prototype.getInputWidth = function() {
  return 20;
}

LuluGroupInterestAdder.prototype.submitEditor = function() {
  var gfe = this;
  if(! this.getEditorValue().length) {
    this.mContents.innerHTML = '';
    this.postSaveFinished();
    return;
  }

  var newtags = this.getEditorValue().split(/, */);
  for(var i = 0; i < newtags.length; i++) {
    if(newtags[i]) {
      this.mGroup.addTag(newtags[i], function(grp,json) { gfe.saveFinished(grp, json); });
    }
  }
};

LuluGroupInterestAdder.prototype.saveFinished = function(iGroup, iJSON) {
  this.mContents.innerHTML = '';

  if(!iJSON.ok) {
    alert(iJSON.message);
    this.postSaveFinished();
    return;
  }

  var interestsList = document.getElementById('interest-listing');
  var newtaglisting = document.createElement('span');
  newtaglisting.id = 'interest-' + iJSON.tag_id;
  $DOM.addClass(newtaglisting, 'interestListing');
  interestsList.appendChild(newtaglisting);
  newtaglisting.innerHTML = ' <a href="http://www.lulu.com/browse/search.php?fKeywords=' + iJSON.tag + '">' + iJSON.tag + '</a> <span class="interestRemover" onclick="groupEditor.removeInterest(' + iJSON.tag_id + ')">X</span>';

  this.postSaveFinished();
};

var LuluGroupEditor = function(iGroup, iMyGroupRole, iIsAdmin) {
  this.mGroup = iGroup;
  if(!this.mGroup) {
    alert('New editor has no group');
  }

  this.mMyGroupRole = iMyGroupRole;
  this.mIsAdmin = iIsAdmin;

  var thisGroupEditor = this;

  var memberRules = {
    '.pending-member' : function(element) {
      element.onclick = function() {
        thisGroupEditor.showMenuForElement(thisGroupEditor.pendingMenu, element);
      }
    },
    '.current-member' : function(element) {
      element.onclick = function() {
        thisGroupEditor.showMenuForElement(thisGroupEditor.memberMenu, element);
      }
    }
  };
  Behavior.register(memberRules);

  YAHOO.util.Event.onContentReady('pageBody', this.finishSetup, this);
  new LULU.IntervalTimerHack();
};

LuluGroupEditor.prototype.onApproveMemberDone = function(iResults, iMemberElement) {
  if(!iResults.ok) {
    alert(iResults.message);
    return;
  }

  iMemberElement.id = 'member-user-' + iResults.acct_id;
  iMemberElement.className = 'current-member';
  if(iResults.role_type >= 20) {
    $DOM.addClass(iMemberElement, 'is-moderator');
    if(iResults.role_type >= 30) {
      $DOM.addClass(iMemberElement, 'is-admin');
    }
  }
  Behavior.apply();
  window.location.reload();
};

LuluGroupEditor.prototype.onApproveMemberClick = function(domEvent) {
  /* Approve this pending member */

  if(confirm('Do you want to approve this request to join the group?')) {
    reqID = parseInt(this.pendingMenu.forElement.id.substr('workrequest-'.length));

    lge = this;
    this.mGroup.approveSubmission(reqID, function(thisGroup, iResults) { lge.onApproveMemberDone(iResults, lge.pendingMenu.forElement); });
  }
};

LuluGroupEditor.prototype.onDenyMemberDone = function(iResults, iMemberElement) {
  if(!iResults.ok) {
    alert(iResults.message);
    return;
  }

  iMemberElement.parentNode.removeChild(iMemberElement);
  window.location.reload();
};

LuluGroupEditor.prototype.onDenyMemberClick = function(domEvent) {
  /* Deny this pending member */

  if(confirm('Do you want to deny this request to join the group?')) {
    reqID = parseInt(this.pendingMenu.forElement.id.substr('workrequest-'.length));

    lge = this;
    this.mGroup.denySubmission(reqID, function(thisGroup, iResults) { lge.onDenyMemberDone(iResults, lge.pendingMenu.forElement); });
  }
};

LuluGroupEditor.prototype.onRemoveMemberDone = function(iResults, iMemberElement) {
  if(!iResults.ok) {
    alert(iResults.message);
    return;
  }

  iMemberElement.parentNode.removeChild(iMemberElement);
  window.location.reload();
};

LuluGroupEditor.prototype.onRemoveMemberClick = function(domEvent) {
  /* Remove this member */

  if(confirm('Do you want to remove this member?')) {
    acctID = parseInt(this.memberMenu.forElement.id.split('-')[2]);

    lge = this;
    this.mGroup.removeMember(acctID, function(thisGroup, iResults) { lge.onRemoveMemberDone(iResults, lge.memberMenu.forElement); });
  }
};

LuluGroupEditor.prototype.onStoreMemberClick = function(domEvent) {
  /* View a member's storefront */

  var acctID = parseInt(this.memberMenu.forElement.id.split('-')[2]);

  window.open('http://stores.lulu.com/store.php?fAcctID=' + acctID);
};

LuluGroupEditor.prototype.onMsgMemberClick = function(domEvent) {
  /* Send a lulu message to this member */

  var acctID = parseInt(this.memberMenu.forElement.id.split('-')[2]);
  var acctName = this.memberMenu.forElement.innerHTML;

  this.mLulumsgDialog.sendMessage(acctID, acctName);
};

LuluGroupEditor.prototype.onRoleChangeMemberDone = function(iResults, iMemberElement) {
  if(!iResults.ok) {
    alert(iResults.message);
    return;
  }

  if(iResults.new_role_type == 10) {
    $DOM.removeClass(iMemberElement, 'is-moderator');
    $DOM.removeClass(iMemberElement, 'is-admin');
  } else if(iResults.new_role_type == 20) {
    $DOM.addClass(iMemberElement, 'is-moderator');
    $DOM.removeClass(iMemberElement, 'is-admin');
  } else if(iResults.new_role_type == 30) {
    $DOM.addClass(iMemberElement, 'is-moderator');
    $DOM.addClass(iMemberElement, 'is-admin');
  }

  window.location.reload();
};

LuluGroupEditor.prototype.changeMemberRole = function(newRole, newRoleName) {
  if(confirm( "Do you want to change this member\'s role to %s?".replace('%s', newRoleName) )) {
    acctID = parseInt(this.memberMenu.forElement.id.split('-')[2]);

    lge = this;
    this.mGroup.changeMemberRole(acctID, newRole, function(thisGroup, iResults) { lge.onRoleChangeMemberDone(iResults, lge.memberMenu.forElement); });
  }
};

LuluGroupEditor.prototype.onPromoteMemberClick = function(domEvent) {
  var newRole, newRoleName;

  if($DOM.hasClass(this.memberMenu.forElement, 'is-admin')) {
    throw new Error("Can\'t promote an admin!");
  } else if($DOM.hasClass(this.memberMenu.forElement, 'is-moderator')) {
    newRole = 30;
    newRoleName = 'Administrator';
  } else {
    newRole = 20;
    newRoleName = 'Moderator';
  }

  return this.changeMemberRole(newRole, newRoleName);
};

LuluGroupEditor.prototype.onDemoteMemberClick = function(domEvent) {
  var newRole, newRoleName;

  if($DOM.hasClass(this.memberMenu.forElement, 'is-admin')) {
    if($DOM.hasClass(this.memberMenu.forElement, 'is-me')) {
      newRole = 20;
      newRoleName = 'Moderator';
    } else {
      throw new Error("Can\'t demote an admin!");
    }
  } else if($DOM.hasClass(this.memberMenu.forElement, 'is-moderator')) {
    newRole = 10;
    newRoleName = 'Member';
  } else {
    throw new Error("Can\'t demote a normal member!");
  }

  return this.changeMemberRole(newRole, newRoleName);
};

LuluGroupEditor.prototype.setupPendingMemberMenu = function() {
  this.pendingMenu = new YAHOO.widget.Menu('member-pending-menu');
  this.pendingMenu.approveItem = new YAHOO.widget.MenuItem("Approve");
  this.pendingMenu.addItem(this.pendingMenu.approveItem);
  this.pendingMenu.denyItem = new YAHOO.widget.MenuItem("Deny");
  this.pendingMenu.addItem(this.pendingMenu.denyItem);
  this.pendingMenu.render(document.body);
  this.pendingMenu.denyItem.clickEvent.subscribe(this.onDenyMemberClick, this, true);
  this.pendingMenu.approveItem.clickEvent.subscribe(this.onApproveMemberClick, this, true);

  var lge = this;
  this.pendingMenu.showForElement = function(iElement) {
    lge.pendingMenu.forElement = iElement;
    lge.pendingMenu.show();
  }
};

LuluGroupEditor.prototype.setupMemberMenu = function() {
  this.memberMenu = new YAHOO.widget.Menu('member-menu');
  this.memberMenu.storeItem = new YAHOO.widget.MenuItem("View Storefront");
  this.memberMenu.addItem(this.memberMenu.storeItem);
  this.memberMenu.msgItem = new YAHOO.widget.MenuItem("Send Message");
  this.memberMenu.addItem(this.memberMenu.msgItem);
  this.memberMenu.removeItem = new YAHOO.widget.MenuItem("Remove");
  this.memberMenu.addItem(this.memberMenu.removeItem);
  this.memberMenu.promoteItem = new YAHOO.widget.MenuItem("Promote");
  this.memberMenu.addItem(this.memberMenu.promoteItem);
  this.memberMenu.demoteItem = new YAHOO.widget.MenuItem("Demote");
  this.memberMenu.addItem(this.memberMenu.demoteItem);

  this.memberMenu.storeItem.clickEvent.subscribe(this.onStoreMemberClick, this, true);
  this.memberMenu.msgItem.clickEvent.subscribe(this.onMsgMemberClick, this, true);
  this.memberMenu.removeItem.clickEvent.subscribe(this.onRemoveMemberClick, this, true);
  this.memberMenu.promoteItem.clickEvent.subscribe(this.onPromoteMemberClick, this, true);
  this.memberMenu.demoteItem.clickEvent.subscribe(this.onDemoteMemberClick, this, true);

  this.memberMenu.render(document.body);

  this.memberMenu.msgItem.cfg.setProperty('disabled', true);
  lge = this;

  this.memberMenu.showForElement = function(iElement) {
    var demoteAvailable = true;
    var promoteAvailable = true;
    var removeAvailable = true;

    lge.memberMenu.forElement = iElement;

    var thisMemberRole = 10;
    if($DOM.hasClass(iElement, 'is-moderator')) {
      thisMemberRole = 20;
    }
    if($DOM.hasClass(iElement, 'is-admin')) {
      thisMemberRole = 30;
    }

    promoteAvailable = ((thisMemberRole < lge.mMyGroupRole) || lge.mIsAdmin) && (thisMemberRole < 30);
    demoteAvailable = (thisMemberRole < lge.mMyGroupRole) || lge.mIsAdmin;
    removeAvailable = (thisMemberRole < lge.mMyGroupRole) || lge.mIsAdmin;

    if($DOM.hasClass(iElement, 'is-me')) {
      removeAvailable = true;
      demoteAvailable = (thisMemberRole > 10);
    }

    lge.memberMenu.promoteItem.cfg.setProperty('disabled', !promoteAvailable);
    lge.memberMenu.demoteItem.cfg.setProperty('disabled', !demoteAvailable);
    lge.memberMenu.removeItem.cfg.setProperty('disabled', !removeAvailable);

    lge.memberMenu.show();
  }
};

LuluGroupEditor.prototype.showMenuForElement = function(iMenu, iElement) {
  iMenu.forElement = iElement;
  elRegion = $DOM.getRegion(iElement);
  iMenu.cfg.setProperty('x', elRegion.left);
  iMenu.cfg.setProperty('y', elRegion.bottom);
  iMenu.showForElement(iElement);
};

LuluGroupEditor.prototype.finishSetup = function(me) {
  me.setupJoinDialog();
  me.setupLeaveDialog();
  me.setupNotificationPreferencesDialog();
  me.setupMemberMenu();
  me.setupPendingMemberMenu();
  me.setupNotificationMessageDialog();
  me.setupPermissionSettingsDialog();
  me.setupContentSubmissionDialog();
  me.setupMemberInvitationDialog();
  me.setupMessagingDialog();
};

LuluGroupEditor.prototype.editURL = function(iContentsID, iFieldName, iMenuItemID) {
  if(!this.mGroup) {
    alert("Edited field has no group");
  }
  return new LuluGroupURLEditor(this.mGroup, iContentsID, iFieldName, iMenuItemID);
};

LuluGroupEditor.prototype.editDescription = function(iContentsID, iFieldName, iMenuItemID) {
  if(!this.mGroup) {
    alert("Edited field has no group");
  }
  return new LuluGroupDescriptionEditor(this.mGroup, iContentsID, iFieldName, iMenuItemID);
}

LuluGroupEditor.prototype.editField = function(iContentsID, iFieldName, iMenuItemID) {
  if(!this.mGroup) {
    alert("Edited field has no group");
  }
  return new LuluGroupFieldEditor(this.mGroup, iContentsID, iFieldName, iMenuItemID);
};

LuluGroupEditor.prototype.addInterest = function(iMenuItemID) {
  return new LuluGroupInterestAdder(this.mGroup, 'interest-adder', iMenuItemID);
};

LuluGroupEditor.prototype.removeInterestComplete = function(iJSON) {
  if(!iJSON.ok) {
    alert(iJSON.message);
    return;
  }

  var interestsList = document.getElementById('interest-listing');
  var interestItem = document.getElementById('interest-' + iJSON.tag_id);
  interestsList.removeChild(interestItem);
};

LuluGroupEditor.prototype.removeInterest = function(iTagID) {
  var ge = this;
  this.mGroup.removeTag(iTagID, function(grp, json) { ge.removeInterestComplete(json); });
};

LuluGroupEditor.prototype.reallySetupLeaveDialog = function() {
  var handleSubmit = function() {
    this.hide();
    document.getElementById('leave-group-form').submit();
  };

  var handleCancel = function() {
    this.hide();
    this.cancel();
  };

  var handleSuccess = function(o) {
    var response = o.responseText;
    response = response.split("<!")[0];
    document.getElementById("resp").innerHTML = response;
    eval(response);
  };

  var handleFailure = function(o) {
    alert("Submission failed: " + o.status);
  };

  this.mLeaveDialog = new YAHOO.widget.Dialog("leave-dialog",
               { width: "400px",
                   fixedcenter: true,
                   //draggable: true,
                   visible: false,
                   constraintoviewport: true,
                   buttons: [ { text:'Leave This Group', handler:handleSubmit, isDefault:true },
                        { text:'Cancel', handler:handleCancel } ]
                   } );
  $DOM.setStyle('leave-dialog', 'display', 'block');

  // Wire up the success and failure handlers
  this.mLeaveDialog.callback = { success:handleSuccess,
              failure:handleFailure };

  this.mLeaveDialog.render();
}

LuluGroupEditor.prototype.setupLeaveDialog = function() {
  YAHOO.util.Event.addListener("leaveGroup", "click", this.leaveGroup, this, true);
};

LuluGroupEditor.prototype.leaveGroup = function() {
  if(! this.mLeaveDialog) {
    this.reallySetupLeaveDialog();
  }

  this.mLeaveDialog.show();
};

LuluGroupEditor.prototype.setupJoinDialog = function() {
  YAHOO.util.Event.addListener("joinGroup", "click", this.joinGroup, this, true);
}

LuluGroupEditor.prototype.reallySetupJoinDialog = function() {
  var handleSubmit = function() {
    this.hide();
    document.getElementById('join-group-form').submit();
  };

  var handleCancel = function() {
    this.hide();
    this.cancel();
  };

  var handleSuccess = function(o) {
    var response = o.responseText;
    response = response.split("<!")[0];
    document.getElementById("resp").innerHTML = response;
    eval(response);
  };

  var handleFailure = function(o) {
    alert("Submission failed: " + o.status);
  };

  this.mJoinDialog = new YAHOO.widget.Dialog("join-dialog",
               { width: "400px",
                   fixedcenter: true,
                   visible: false,
                   //draggable: true,
                   constraintoviewport: true,
                   buttons: [ { text:'Join This Group', handler:handleSubmit, isDefault:true },
                        { text:'Cancel', handler:handleCancel } ]
                   } );
  $DOM.setStyle('join-dialog', 'display', 'block');

  // Wire up the success and failure handlers
  this.mJoinDialog.callback = { success:handleSuccess,
              failure:handleFailure };

  this.mJoinDialog.render();
};

LuluGroupEditor.prototype.joinGroup = function() {
  if(! this.mJoinDialog) {
    this.reallySetupJoinDialog();
  }

  this.mJoinDialog.show();
};

LuluGroupEditor.prototype.reallySetupNotificationPreferencesDialog = function() {
  var handleSubmit = function() {
    this.hide();
    this.submit();
  };

  var handleCancel = function() {
    this.hide();
    this.cancel();
  };

  var handleSuccess = function(o) {
    var response = o;
    var json = evalJSON(response.responseText);
    if(!json || !json.ok) {
      alert((json && json.message)?json.message:"Save failed");
    }
  };

  var handleFailure = function(o) {
    alert("Submission failed: " + o.status);
  };

  var handleShowGotData = function(myDlg, jsonData) {
    /* Loads the stored data and stuffs it into the checkboxes before the user starts changing the settings */
    if(!jsonData || !jsonData.ok) {
      myDlg.hide();
      alert((jsonData && jsonData.message)?jsonData.message:"Could not retrieve settings");
      return;
    }

    /* And then, a miracle happens...
     * As far as code goes, this is pretty ugly, but we have collapse a bunch of actual backend settings into one
     */
    var checkboxes = $DOM.getElementsByClassName('noteprefs-setting-checkbox', 'input', document.getElementById('noteprefs-form'));
    jsonData.values.sort(function(a, b) { return a.event.length - b.event.length; });

    for(var i = 0; i < checkboxes.length; i++) {
      var isChecked = true;

      var checkbox = checkboxes[i];

      cbname = checkbox.getAttribute('name');
      cbname = cbname.substr('FORM['.length);
      cbname = cbname.substr(0, cbname.length - 1);
      cbpieces = cbname.split('!');
      audience = cbpieces[1];
      evpath = cbpieces[0];

      for(var j = 0; j < jsonData.values.length; j++) {
        if((evpath == jsonData.values[j].event
            || (jsonData.values[j].event.substr(0, evpath.length + 1) == (evpath + '/')))
           && jsonData.values[j].audience == audience) {
          isChecked = jsonData.values[j].enabled?true:false;
        }
      }

      checkbox.checked = isChecked;
    }
  };

  var handleShow = function(o) {

    var myDialog = this;
    var params = requestManager.makeParams({fOpName:'load_notification_preferences',
                       fGroupID:myDialog.mGroupEditor.mGroup.mGroupID});

    var callback = {
      success : function (response) {
        if(response.status >= 300) {
          return handleShowGotData(myDialog, null);
        }

        var json = evalJSON(response.responseText);
        handleShowGotData(myDialog, json);
      },

      failure: function (response) {
        handleShowGotData(myDialog, null);
      },

      scope: myDialog
    };

    requestManager.makeRequest('callbacks/group_edit.php', 'POST', params, callback);
  };

  this.mNotePrefsDialog = new YAHOO.widget.Dialog("noteprefs-dialog",
              { width: "400px",
                  fixedcenter: true,
                  visible: false,
                   //draggable: true,
                  constraintoviewport: true,
                  buttons: [ { text:"Save Preferences", handler:handleSubmit, isDefault:true },
                       { text:"Cancel", handler:handleCancel } ]

                  } );
  $DOM.setStyle('noteprefs-dialog', 'display', 'block');
  this.mNotePrefsDialog.beforeShowEvent.subscribe(handleShow, this.mNotePrefsDialog, true);
  this.mNotePrefsDialog.mGroupEditor = this;

  // Wire up the success and failure handlers
  this.mNotePrefsDialog.callback = { success:handleSuccess,
             failure:handleFailure };

  this.mNotePrefsDialog.render();
}

LuluGroupEditor.prototype.setupNotificationPreferencesDialog = function() {
  YAHOO.util.Event.addListener("showNoteprefs", "click", this.showNotePrefsDialog, this, true);
};

LuluGroupEditor.prototype.showNotePrefsDialog = function() {
  if(! this.mNotePrefsDialog) {
    this.reallySetupNotificationPreferencesDialog();
  }

  this.mNotePrefsDialog.show();
};

LuluGroupEditor.prototype.setupNotificationMessageDialog = function() {
  this.mNoteMsgDialog = new LuluGroupNotificationMessageDialog(this.mGroup);
};

LuluGroupEditor.prototype.setupPermissionSettingsDialog = function() {
  this.mPermSetDialog = new LuluGroupPermissionSettingsDialog(this.mGroup);
};

LuluGroupEditor.prototype.reallySetupContentSubmissionDialog = function() {
  var handleSubmit = function() {
    this.hide();
    document.getElementById('submit-content-form').submit();
  };

  var handleCancel = function() {
    this.hide();
    this.cancel();
  };

  var handleSuccess = function(o) {
    var response = o;
    var json = evalJSON(response.responseText);
    if(!json || !json.ok) {
      alert((json && json.message)?json.message:"Content Submission failed");
    }
  };

  var handleFailure = function(o) {
    alert("Submission failed: " + o.status);
  };

  this.mContentSubmissionDialog = new YAHOO.widget.Dialog("content-panel",
                     {
                    width:"400px",
                    fixedcenter: true,
                    //draggable: true,
                    visible:false,
                    constraintoviewport:true,
                    buttons: [ { text:"Submit Content", handler:handleSubmit, isDefault:true },
                       { text:"Cancel", handler:handleCancel } ]
                   } );
  $DOM.setStyle('content-panel', 'display', 'block');

  this.mContentSubmissionDialog.render();
}

LuluGroupEditor.prototype.submitContent = function() {
  if(! this.mContentSubmissionDialog) {
    this.reallySetupContentSubmissionDialog();
  }

  this.mContentSubmissionDialog.show();
}

LuluGroupEditor.prototype.setupContentSubmissionDialog = function() {
  YAHOO.util.Event.addListener("show-contentsubmitdialog", "click", this.submitContent, this, true);
};

LuluGroupEditor.prototype.reallySetupMemberInvitationDialog = function() {
  // Define various event handlers for Dialog
  var handleSubmit = function() {
    this.submit();
    this.hide();
  };
  var handleCancel = function() {
    this.hide();
    this.cancel();
  };
  var handleSuccess = function(o) {
    var json = evalJSON(o.responseText);
    if(!json || !json.ok) {
      alert((json && json.message)?json.message:'Save failed');
      return;
    }
    var did_alerts = false;
    if(json.error_strings && json.error_strings.length) {
      alert("The following users could not be found: " + json.error_strings.join(', '));
      did_alerts = true;
    }
    if(json.denied_strings && json.denied_strings.length) {
      alert("Permission was denied to invite the following users: " + json.denied_strings.join(', '));
      did_alerts = true;
    }
    if(!did_alerts) {
      alert("Your invitation has been sent.");
    }
  };

  var handleFailure = function(o) {
    alert('Submission failed: ' + o.status);
  };

  // Instantiate the Dialog
  this.mInviteDialog = new YAHOO.widget.Dialog("inviteOthers",
                 { width : "400px",
                     fixedcenter : true,
                     visible : false,
                   //draggable: true,
                   constraintoviewport : true,
                     buttons : [ { text:"Send Invitation", handler:handleSubmit, isDefault:true },
                     { text:"Cancel", handler:handleCancel } ]
                     } );
  $DOM.setStyle('inviteOthers', 'display', 'block');

  // Wire up the success and failure handlers
  this.mInviteDialog.callback = { success: handleSuccess,
          failure: handleFailure };

  // Render the Dialog
  this.mInviteDialog.render();
}

LuluGroupEditor.prototype.inviteMember = function() {
  if(! this.mInviteDialog) {
    this.reallySetupMemberInvitationDialog();
  }

  this.mInviteDialog.show();
}

LuluGroupEditor.prototype.setupMemberInvitationDialog = function() {
  YAHOO.util.Event.addListener("showInvite", "click", this.inviteMember, this, true);
};

LuluGroupEditor.prototype.setupMessagingDialog = function() {
  this.mLulumsgDialog = new LuluMessageSender();
};

var LuluAvatarEditor = function(iElementID, iSize, iClassName, iObjectID) {
	this.mElementID = iElementID;
	this.mIFrame = null;

	this.mSize = iSize;
	this.mClassName = iClassName;
	this.mObjectID = iObjectID;

	YAHOO.util.Event.onContentReady(iElementID, this.setupElements, this, true);
}

LuluAvatarEditor.prototype.setupElements = function() {
	var me = this;

	this.mElement = $(this.mElementID);

	var els;
	els = $DOM.getElementsByClassName('avatar-form', null, this.mElement);
	this.mForm = els[0];
	this.mForm.onsubmit = function() { me.formSubmitted(); };
	els = $DOM.getElementsByClassName('avatar-edit-link', null, this.mElement);
	this.mEditLink = els[0];
	this.mEditLink.onclick = function() {
		me.editClicked();
	}

	els = $DOM.getElementsByClassName('avatar-submit', null, this.mElement);
	this.mSubmit = els[0];
	this.mSubmit.onclick = function() {
		me.submitClicked();
	}
	els = $DOM.getElementsByClassName('avatar-cancel', null, this.mElement);
	this.mCancel = els[0];
	this.mCancel.onclick = function() {
		me.cancelClicked();
	}

	els = $DOM.getElementsByClassName('avatar-image', null, this.mElement);
	this.mImage = els[0];
}

LuluAvatarEditor.prototype.startEditing = function() {
	$DOM.setStyle(this.mEditLink, 'visibility', 'hidden');
	$DOM.setStyle(this.mForm, 'visibility', 'visible');
}

LuluAvatarEditor.prototype.stopEditing = function() {
	$DOM.setStyle(this.mEditLink, 'visibility', 'visible');
	$DOM.setStyle(this.mForm, 'visibility', 'hidden');
}

LuluAvatarEditor.prototype.cancelClicked = function() {
	this.stopEditing();
}

LuluAvatarEditor.prototype.editClicked = function() {
	this.startEditing();
}

LuluAvatarEditor.prototype.submitClicked = function() {
	var me = this;

	$DOM.setStyle(this.mForm, 'visibility', 'hidden');

	if(! this.mIFrame) {
		/* We create an iframe for each submission to avoid problems with the back/reload buttons */
		var myframename = 'avatarUpload' + Math.floor(Math.random() * 99999);
		this.mIFrame = document.createElement('iframe');
		this.mIFrame.id = myframename;
		this.mIFrame.setAttribute('name', myframename);
		$DOM.setStyle(this.mIFrame, 'display', 'none');
		this.mIFrame.onload = function() { me.uploadDone(); };

		this.mForm.appendChild(this.mIFrame);

		this.mForm.setAttribute('target', myframename);
	}

	this.mForm.submit();

	return true;
}

LuluAvatarEditor.prototype.formSubmitted = function() {
	return true;
}

LuluAvatarEditor.prototype.handleResponse = function(response) {
	if(response === null) {
		//		alert("Image upload failed");
		return;
	}

	var json = evalJSON(response);
	if(!json || !json.ok) {
		alert((json && json.message)?json.message:'Upload failed');
		return;
	}

	this.mImage.setAttribute('src', json.urls[this.mSize]);
}

LuluAvatarEditor.prototype.uploadDone = function() {
	/* This magic (and the hidden iframe trick) is courtesy of http://www.webtoolkit.info/ajax-file-upload.html */
	if(this.mIFrame.contentDocument) {
		var doc = this.mIFrame.contentDocument;
	} else if(this.mIFrame.contentWindow) {
		var doc = this.mIFrame.contentWindow.document;
	} else if(this.mIFrame.document) {
		var doc = this.mIFrame.document;
	} else {
		var doc = document.frames[this.mIFrame.id];
	}

	if(doc.location.href == 'about:blank' || ! doc.location.href) {
		this.handleResponse(null);
	} else {
		this.handleResponse(doc.body.innerHTML);
	}

/*	this.mForm.removeChild(this.mIFrame);
	this.mIFrame = null; */
	this.stopEditing();
}
var LuluMessageSender = function() {
	this.mDestElement = $('lulumsgsender-dialog-dest');
	this.mDestTextElement = $('lulumsgsender-dialog-desttext');
	this.mSubjectElement = $('lulumsgsender-dialog-msgsubject');
	this.mTextElement = $('lulumsgsender-dialog-msgtext');
}

LuluMessageSender.prototype.setup = function() {
	var me = this;
	this.mDialog = new YAHOO.widget.Dialog('lulumsgsender-dialog', { width: '450px',
							       fixedcenter: true,
							       visible: false,
							       modal: false,
							       constraintoviewport: true,
							       buttons: [ {text:'Send', handler: me.handleSubmit, isDefault:true },
									  {text:'Cancel', handler: me.handleCancel } ] });
	$DOM.setStyle('lulumsgsender-dialog', 'display', 'block');
	this.mDialog.callback = { success:me.handleSuccess,
				  failure:me.handleFailure };

	this.mDialog.render();
}

LuluMessageSender.prototype.doShow = function() {
	if( ! this.mDialog) {
		this.setup();
	}

	this.mDialog.show();
}

LuluMessageSender.prototype.sendMessages = function(iUserIDs, iUserNames) {
	this.mTextElement.value = '';
	this.mSubjectElement.value = '';
	this.mDestTextElement.innerHTML = iUserNames.join(', ');
	this.mDestElement.value = iUserIDs.join(', ');
	this.doShow();
}

LuluMessageSender.prototype.sendMessage = function(iUserID, iUserName) {
	this.mTextElement.value = '';
	this.mSubjectElement.value = '';
	this.mDestTextElement.innerHTML = iUserName;
	this.mDestElement.value = iUserID;
	this.doShow();
}

LuluMessageSender.prototype.handleSubmit = function() {
	this.hide();
	this.submit();
}

LuluMessageSender.prototype.handleCancel = function() {
	this.hide();
}

LuluMessageSender.prototype.handleSuccess = function(o) {
	var response = o;
	var json = evalJSON(o.responseText);
	if(!json || !json.ok) {
		alert((json && json.message)?json.message:'Save failed');
	}
}

LuluMessageSender.prototype.handleFailure = function() {
	alert("Save failed: " + o.status);
}
