/* Copyright (c) 2006-2009, Apple Inc. All rights reserved. */

var GroupWikiListingPage = Class.createWithSharedInstance('groupWikiListingPage', true);
GroupWikiListingPage.prototype = {

	initialize: function()
	{
		// bail if this isn't actually the group wiki listing
		if (!$('wikid').hasClassName('serverhome') || !$('wikid').hasClassName('groups')) return invalidate;

		bindEventListeners(this, [
			'onCreateWikiButtonClick'
		]);

		if (window.parent && parent.addService) parent.addService('groups', '/groups/');
		if (window.parent && parent.addGroups) parent.addGroups($$('ul.contentlist span.title').collect(function(span) {
			return {title:span.firstChild.nodeValue, href:span.up('a').href};
		}));
		
		var s = server(); // force shared instance creation
		s.beforegroupwikis_checkSessionAuthorization = s.checkSessionAuthorization;
		s.checkSessionAuthorization = function(inCallback, inOptAction, inOptPath) {
			s.beforegroupwikis_checkSessionAuthorization(inCallback, inOptAction);
		};
		// patch login method to remove the path from the args
		s.beforegrouplisting_login = s.login;
		s.login = function(inCallback, inUsername, inPassword, inOptAuthorizePath, inOptPersistent) {
			s.beforegrouplisting_login(inCallback, inUsername, inPassword, null, inOptPersistent);
		};
		
		// patch some UID stuff -- otherwise we set the test cookie (cookies=1) in /users/list
		uid().mBaseLocation = '/';
		
		if ($('create_entity_button')) $('create_entity_button').observe('click', this.onCreateWikiButtonClick);
		if ($('paginator_choose')) paginator();
		
		this.entityList = new EntityList('entity_list');
		
		if (window.location.hash.match(/^#create/))
		{
			this.openWikiSetupAssistant();
		}
	},
	
	openWikiSetupAssistant: function()
	{
		if (serverui().userIsAuthenticated()) {
			this.onUserAuthorized();
		} else {
			// need to force the login window... for some reason the acl_cache is auto set to 'write' for unauthed users
			serverui().ensureLogin(this.onUserAuthorized.bind(this), 'write', false, true);
		}
	},
	
	onUserAuthorized: function()
	{
		wikiSetupAssistant().show();
		
		var params = $H((window.location.search || '').toQueryParams());
		var shortName = params.get('shortName');
		var displayName = params.get('displayName');
		
		if (displayName) {
			$('wiki_setup_name').value = displayName;
			wikiSetupAssistant().panels.selected().updateState();
		}
		if (displayName && shortName) {
			wikiSetupAssistant().panels.itemAtIndex(2).chooser.setAccessLevel(ACLChooser.ACCESS_PRIVATE);
			wikiSetupAssistant().panels.itemAtIndex(2).chooser.userlist.addTag(displayName, false, shortName, "readwrite");
		}
		if (displayName || shortName) {
			wikiSetupAssistant().settings.set('supportedServices', ['wiki', 'weblog', 'webCalendar', 'webMailingList']);  // #6695140
		}
	},
	
	onCreateWikiButtonClick: function(e)
	{
		e.stop();
		this.openWikiSetupAssistant();
	}

};




var Panel = Class.create({
	initialize: function(element)
	{
		this.element = $(element);
	},
	getParent: function()
	{
		return this._parent;
	},
	setParent: function(parent)
	{
		this._parent = parent;
	},
	show: function()
	{
		this.element.show();
	},
	hide: function()
	{
		this.element.hide();
	},
	select: function()
	{
		this.getParent().select(this);
	}
});
var PanelSet = Class.create({
	_panels: null,
	_selected: null,
	
	initialize: function()
	{
		this._panels = [];
	},
	add: function(panel)
	{
		panel.setParent(this);
		this._panels.push(panel);
	},
	remove: function(panel)
	{
		panel.setParent(null);
		this._panels = this._panels.without(panel);
	},
	select: function(panel)
	{
		this._panels.each(function(p) {
			(p == panel) ? p.show(): p.hide();
		});
		this._selected = panel;
	},
	
	// panel accessors...
	first: function() { return this._panels.first(); },
	last: function() { return this._panels.last(); },
	all: function() { return this._panels; },
	selected: function() { return this._selected; },
	previous: function() { return this._selectedOffset(-1); },
	next: function() { return this._selectedOffset(1); },
	itemAtIndex: function(idx) { return this._panels[idx]; },
	
	_selectedOffset: function(offset)
	{
		var firstIdx  = 0;
		var lastIdx   = this._panels.length - 1;
		var offsetIdx = this._panels.indexOf(this.selected()) + offset;
		if (offsetIdx < firstIdx) {
			offsetIdx = lastIdx;
		} else if (offsetIdx > lastIdx) {
			offsetIdx = firstIdx;
		}
		return this._panels[offsetIdx];
	}
});





var SetupAssistant = Class.createWithSharedInstance('wikiSetupAssistant');
SetupAssistant.prototype = {

	initialize: function()
	{
		this.element = $('wiki_setup');
		if (!this.element) return invalidate;
		
		// relocate the dialog to the end of the document
		d.body.appendChild( this.element.remove() );
		
		bindEventListeners(this, [
			'onFormSubmit',
			'onCancelButtonClick',
			'onPrevButtonClick',
			'onNextButtonClick',
			'onDoneButtonClick',
			'onDismissButtonClick',
			'onGoToButtonClick',
			'onDocumentKeypress'
		]);
		this.onProvisionWikiSuccess = this.onProvisionWikiSuccess.bind(this);
		this.onProvisionWikiFailure = this.onProvisionWikiFailure.bind(this);
		
		// default settings
		this.settings = $H({
			longName:    '',
			Description: '',
			themeName:   getMetaTagValue('apple_default_theme_id'),
			readAccess:  'unauthenticated',
			writeAccess: 'unauthenticated',
			adminAccess: [], // empty array == "only owner and server admins"
			notifyNewMembers: false
		});
		
		// ensure that the dialogManager has initialized and thus that #dialog_mask exists...
		dialogManager();
		this.mask = $('dialog_mask');
		
		this.element.down('form').observe('submit', this.onFormSubmit);
		this.element.select('.button.cancel').invoke('observe', 'click', this.onCancelButtonClick);
		this.element.select('.button.prev').invoke('observe', 'click', this.onPrevButtonClick);
		this.element.select('.button.next').invoke('observe', 'click', this.onNextButtonClick);
		this.element.select('.button.done').invoke('observe', 'click', this.onDoneButtonClick);
		this.element.select('.button.dismiss').invoke('observe', 'click', this.onDismissButtonClick);
		this.element.select('.button.goto').invoke('observe', 'click', this.onGoToButtonClick);
		
		this.panels = new PanelSet();
		this.panels.add( new SetupAssistant.NamePanel(this.element.down('.panel.name')) );
		this.panels.add( new SetupAssistant.ThemePanel(this.element.down('.panel.theme')) );
		this.panels.add( new SetupAssistant.AccessPanel(this.element.down('.panel.access')) );
		this.panels.add( new SetupAssistant.CompletePanel(this.element.down('.panel.complete')) );
	},
	
	show: function()
	{
		if ( !serverui().userIsAuthenticated() ) return false;
		
		window.scrollTo(0, 0);

		// ensure that the panels are in their default state and that the first panel is selected...
		this.panels.all().invoke('reset');
		this.panels.first().select();
		
		this.mask.show();
		// display hidden so we can get the DOM dimensions
		this.element.setStyle({ visibility: 'hidden' });
		this.element.show();

		// center the dialog
		var offsetTop  = (window.innerHeight || d.documentElement.offsetHeight) - this.element.getHeight();
		var offsetLeft = this.element.getOffsetParent().getWidth() - this.element.getWidth();
		this.element.setStyle({
			top:  Math.max( offsetTop / 4,  0 ) + 'px',
			left: Math.max( offsetLeft / 2, 0 ) + 'px'
		});

		// hide and return visibility so we can animate...
		this.element.hide();
		this.element.setStyle({
			position: MozillaFixes.isGecko ? 'fixed' : 'absolute',
			visibility: 'visible'
		});

		// now animate open...
		new Effect.Appear(this.element, { duration:0.3, afterFinish: function() {
			$('wiki_setup_name').focus();
		}});
		
		d.observe('keypress', this.onDocumentKeypress);
	},
	hide: function()
	{
		d.stopObserving('keypress', this.onDocumentKeypress);
		this.mask.hide();
		new Effect.Fade(this.element, { duration:0.3 });
	},
	
	onFormSubmit: function(e)
	{
		e.stop();
	},
	// panel button handlers
	onCancelButtonClick: function(e)
	{
		e.stop();
		// clear out any url cruft sent by server admin...
		var l = window.location;
		var hash = l.hash.gsub(/#create/, '');
		var search = l.search.gsub(/[?&]shortName=[^&]+/, '').gsub(/[?&]displayName=[^&]+/, '');
		if ((l.hash != hash) || (l.search != search)) {
			l.href = l.pathname + search;
		}
		// close the dialog
		this.hide();
	},
	onPrevButtonClick: function(e)
	{
		e.stop();
		this.panels.previous().select();
	},
	onNextButtonClick: function(e)
	{
		e.stop();
		this.panels.next().select();
	},
	onDoneButtonClick: function(e)
	{
		e.stop();
		// disable the panel to prevent duplicate submissions
		var panel = this.panels.selected();
		panel.element.select('.controls .button').invoke('disable');
		// update the settings 
		this.settings.update({
			longName:    $F('wiki_setup_name'),
			Description: $F('wiki_setup_description'),
			themeName:   $F('wiki_setup_theme_name')
		});
		var acls = panel.chooser.getACLs();
		this.settings.set('readAccess', acls.read);
		this.settings.set('writeAccess', acls.write);
		if (!$('wiki_setup_access_notify').disabled) {
			this.settings.set('notifyNewMembers', !!$F('wiki_setup_access_notify'));
		}
		// 6725462
		var protocol = (window.location.protocol || 'http');
		var optScheme = protocol.gsub(/:/, '');
		// 6741436
		var optLang = Loc.getBrowserLocale();
		// provision the wiki
		server().provisionGroup([this.onProvisionWikiSuccess, this.onProvisionWikiFailure], this.settings.toObject(), optScheme, optLang).makeRequired();
	},
	onDismissButtonClick: function(e)
	{
		e.stop();
		this.hide();
		groupWikiListingPage().entityList.reload();
	},
	onGoToButtonClick: function(e)
	{
		e.stop();
		var url = this.settings.get('url');
		if (!url) throw new Error('SetupAssistant: no url to redirect to!');
		this.hide();
		window.location = url;
	},
	onDocumentKeypress: function(e)
	{
		if (e.keyCode == Event.KEY_ESC) {
			var btn = this.panels.selected().element.down('.button.cancel');
			if (btn) {
				btn.click();
			} else {
				this.onDismissButtonClick(e); // dismiss button was removed
			}
		}
		if (e.keyCode == Event.KEY_RETURN) {
			var button = this.panels.selected().element.down('.button[default="default"]');
			if (button && button.click) {
				button.click();
			} else if (this.panels.selected().element.hasClassName('complete')) {
				this.onGoToButtonClick(e);
			}
		}
	},
	
	// XML-RPC callbacks
	onProvisionWikiSuccess: function(request, response)
	{
		// set the settings using the settings service so that the welcome email is sent out.
		this.settings.set('url', response);
		var panel = this.panels.selected();
		panel.element.select('.controls .button').invoke('enable');
		// set the wikiname and select the confirmation panel
		var panel = this.panels.next();
		panel.element.down('.confirmation span').update( (this.settings.get('longName') || '').escapeHTML() );
		panel.select();
	},
	onProvisionWikiFailure: function(request, faultCode, faultString)
	{
		if (faultCode == 19) {
			alert(Loc['wiki_setup_name_error_notallowed']);
		}
		else {
			alert(faultCode);
			//alert(Loc['wiki_setup_name_error_misc']);
		}
	}

};



SetupAssistant.Panel = Class.create(Panel, {
	initialize: function(element)
	{
		this.element = $(element);
	},
	reset: function()
	{
	}
});
SetupAssistant.NamePanel = Class.create(SetupAssistant.Panel, {
	initialize: function(element)
	{
		this.element = $(element);
		
		bindEventListeners(this, [
			'onValueChange',
			'onDescriptionKeypress'
		]);
		
		this.onTimerExecute        = this.onTimerExecute.bind(this);
		this.onGetShortNameSuccess = this.onGetShortNameSuccess.bind(this);
		this.onGetShortNameFailure = this.onGetShortNameFailure.bind(this);
		
		// using a timer as a throttle on the validation service.
		// a series of fast keystrokes will keep resetting the timer until a 1/2 sec. pause
		this.timer = new PeriodicalExecuter(this.onTimerExecute, 0.5);
		this.timer.stop();
		
		this.button = this.element.down('.button.next');
		this.url = $('wiki_setup_url_preview');
		
		this.name = $('wiki_setup_name');
		this.name.autocomplete = 'off';
		this.name.observe('keyup',  this.onValueChange);
		this.name.observe('change', this.onValueChange);
		
		this.description = $('wiki_setup_description');
		this.description.observe('keypress', this.onDescriptionKeypress);
	},
	reset: function()
	{
		this.name.value = '';
		this.description.value = '';
		this.updateState();
	},
	updateState: function()
	{
		if (this.name.getValue() == '') {
			this.setShortName('...');
			this.button.disable();
		} else {
			this.button.enable();
		}
	},
	setShortName: function(shortname)
	{
		var url = [
			location.protocol, 
			'//', 
			location.hostname, 
			location.pathname, 
			shortname
		].join('');
		this.url.update(url);
	},
	onValueChange: function(e)
	{
		this.timer.stop();
		this.timer.start();
		this.updateState();
	},
	onDescriptionKeypress: function(e)
	{
		e.stopPropagation(); // prevent enter key from triggering the next panel
	},
	onTimerExecute: function()
	{
		this.timer.stop();
		var value = this.name.getValue();
		if ((value != undefined) && (value != null) && (value != '')) {
			server().groupShortNameFromLongName([this.onGetShortNameSuccess, this.onGetShortNameFailure], value);
		}
	},
	onGetShortNameSuccess: function(request, response)
	{
		this.setShortName(response);
	},
	onGetShortNameFailure: function(request, errorCode, errorString)
	{
		alert(Loc['wiki_setup_name_server_error']);
	}
});
SetupAssistant.ThemePanel = Class.create(SetupAssistant.Panel, {
	initialize: function(element)
	{
		bindEventListeners(this, [
			'onThemeClicked'
		]);
		
		this.element = $(element);
		this.list = this.element.down('ul');
		this.list.observe('click', this.onThemeClicked);
		
		// TODO: start a spinner 
		server().settings.getThemes([
			this.onLoadThemesSuccess.bind(this),
			this.onLoadThemesFailure.bind(this)
		]);
	},
	onLoadThemesSuccess: function( request, response )
	{
		for (var i=0, n=response.length; i < n; i++)
		{
			var theme = response[i];
			// service returns all themes regardless of selectability
			if (!theme.isSelectable) continue;
			
			var item  = Element('li', {
				name:  theme.name,
				title: theme.displayName 
			});
			item.insert(Element('img', { 
				src:  theme.themePath + "/preview.png", 
				alt:  theme.displayName
			}));
			item.insert(Element('span', {
				title: theme.displayName 
			}).update(theme.displayName));
			this.list.insert(item);
		}
		
		var defaultThemeName = getMetaTagValue('apple_default_theme_id');
		// #6416689
		var defaultListItem = this.list.down('li[name="'+ defaultThemeName +'"]');
		if (defaultListItem) {
			this.list.insert({ top: defaultListItem.remove() });
		}
		this.setSelectedThemeByName(defaultThemeName);
	},
	onLoadThemesFailure: function( request, response )
	{
		// TODO: handle error...
	},
	onThemeClicked: function(e)
	{
		var element = e.findElement('li');
		if (element) {
			var themeName = element.readAttribute('name');
			if (themeName) {
				this.setSelectedThemeByName(themeName);
			}
		}
	},
	setSelectedThemeByName: function( name )
	{
		$('wiki_setup_theme_name').value = name;
		var items = this.list.select('li');
		for (var i=0, n=items.length; i < n; i++)
		{
			var item = items[i];
			if (item.readAttribute('name') == name) {
				item.addClassName('selected');
			} else {
				item.removeClassName('selected');
			}
		}
	},
	reset: function()
	{
		this.setSelectedThemeByName( getMetaTagValue('apple_default_theme_id') );
	}

});

SetupAssistant.AccessPanel = Class.create(SetupAssistant.Panel, {
	initialize: function(element)
	{
		this.element = $(element);
		this.chooser = new ACLChooser(this.element.down('.acl-chooser'));
	},
	reset: function()
	{
		this.chooser.reset();
	}
});
SetupAssistant.CompletePanel = Class.create(SetupAssistant.Panel, {
});





if (window.loaded) loaded('group_wiki_listing.js');