
var howToBrowser = Class.create();
Object.extend(howToBrowser.prototype, {
	
	keyDirection: null,
	_didShowNotificationListenerIsSet: false,

	keyLeft: function(evt) {
		if (Element.hasClassName(Event.element(evt), 'howto-content') || Event.element(evt).up('howto-content')) {
			$$('.how-to .active')[0].focus();
			Event.stop(evt);
			return;
		}
		
		var element = this.getListItemFromEvent(evt),
			triggerIndex,
			previousElement = (element.previous()) ? element.previous() : false;
		
		if (element.getAttribute('aria-level') == 1 && previousElement !== false) {
			if (element.getAttribute('aria-expanded') === 'true') element.setAttribute('aria-expanded', 'false');
			this.scrollAndSetFocusForElements(previousElement, element);
		}
	},
	
	keyUp: function(evt) {
		if (Element.hasClassName(Event.element(evt), 'howto-content') || Event.element(evt).up('howto-content')) {
			return;
		}
		
		var element = this.getListItemFromEvent(evt),
			previousElement,
			focusElement;
		
		if (element.getAttribute('aria-level') == 2) {
			previousElement = (element.previous()) ? element.previous() : false;
			if (previousElement) {
				this.setFocusForElements(previousElement, element);
			} else {
				focusElement = $$('.nav-item .active')[0].up('li');
				this.setFocusForElements(focusElement, element);
			}
			
		}
	},
	
	keyRight: function(evt) {
		if (Element.hasClassName(Event.element(evt), 'howto-content') || Event.element(evt).up('howto-content')) {
			return;
		}
		
		var element = this.getListItemFromEvent(evt),
			triggerIndex,
			nextElement = (element.next()) ? element.next() : false,
			contentElement;
		
		if (element.getAttribute('aria-level') == 1 && nextElement !== false) {
			if (element.getAttribute('aria-expanded') === 'true') element.setAttribute('aria-expanded', 'false');
			this.scrollAndSetFocusForElements(nextElement, element);
		} else if (element.getAttribute('aria-level') == 2) {
			contentElement = $$('.howto-content')[0];
			contentElement.setAttribute('tabindex', '0');
			contentElement.setAttribute('aria-level', '3');
			element.setAttribute('aria-expanded', 'true');
			
			Event.stopObserving(contentElement, 'keydown');
			Event.observe(contentElement, 'keydown', this.keyPressHandler.bindAsEventListener(this));
			
			//Element.removeClassName($$('.how-to.activedescendant')[0], 'activedescendant');
			
			contentElement.focus();

			Element.removeClassName(element, 'activedescendant');
			Element.addClassName(contentElement, 'activedescendant');
		}
	},
	
	keyDown: function(evt) {
		if (Element.hasClassName(Event.element(evt), 'howto-content') || Event.element(evt).up('howto-content')) {
			return;
		}
		
		var element = this.getListItemFromEvent(evt),
			focusElement,
			nextElement;
		
		if (element.getAttribute('aria-level') == 1 && Element.hasClassName(element.down('a'), 'active')) {
			element.setAttribute('aria-expanded', 'true');
			
			focusElement = $$('.howto-list .active')[0].up('li');
			this.setFocusForElements(focusElement, element);
		} else if (element.getAttribute('aria-level') == 2) {
			nextElement = (element.next()) ? element.next() : false;
			if (nextElement) this.setFocusForElements(nextElement, element);
		}
	},
	
	getListItemFromEvent: function(evt) {
		Event.stop(evt);
		return Event.findElement(evt, 'li');
	},
	
	scrollAndSetFocusForElements: function(focusElement, currentElement) {
		Element.childElements(currentElement.parentNode).each(function(item, index) {
			if (item === focusElement) triggerIndex = index;
		});
		
		if (triggerIndex !== false) {
			slider.maskInnerDimension = parseInt(currentElement.getWidth() * slider.itemsPerPage);
			slider.scrollToItem(triggerIndex);
			slider.resetPages();
		}

		if (((triggerIndex % slider.itemsPerPage) === 0 && this.keyDirection === 'right') || (((triggerIndex + 1) % slider.itemsPerPage) === 0 && this.keyDirection === 'left')) {
			window.setTimeout(this.setFocusForElements.bind(this, focusElement, currentElement), 500);
		} else {
			this.setFocusForElements(focusElement, currentElement);
		}
		
	},
	
	setFocusForElements: function(focusElement, currentElement) {
		focusElement.down('a').focus();
		if (focusElement.getAttribute('aria-level') === currentElement.getAttribute('aria-level')) {
			currentElement.setAttribute('tabindex', '-1');
			focusElement.setAttribute('tabindex', '0');
		}
		Element.removeClassName(currentElement, 'activedescendant');
		Element.addClassName(focusElement, 'activedescendant');
	},
	
	keyPressHandler: function(evt) {
		switch(evt.keyCode){
			case Event.KEY_LEFT:
				this.keyDirection = 'left';
				this.keyLeft(evt);
				break;
			case Event.KEY_UP:
				this.keyDirection = 'up';
				this.keyUp(evt);
				break;
			case Event.KEY_RIGHT:
				this.keyDirection = 'right';
				this.keyRight(evt);
				break;
			case Event.KEY_DOWN:
				this.keyDirection = 'down';
				this.keyDown(evt);
				break;
			default:
				return;
		}
		
		Event.stop(evt);
	},
	
	willSetSwapView: function(self, view, triggerClassName) {
		var li, ul, triggerClassName, ariaLevel, liId, currentViewIndex;
		
		$$('.browser-selector-link').each(function(trigger, index) {
			li = trigger.up('li'),
			ul = li.parentNode,
			triggerClassName = (Element.hasClassName(trigger, 'nav-link')) ? 'nav-link' : trigger.up('div').id.split('MASKED-')[1] + '-howto-link',
			ariaLevel = (triggerClassName === 'nav-link') ? 1 : 2,
			liId = trigger.href.split('#')[1] + '_' + triggerClassName;

			li.id = liId;
			li.setAttribute('aria-level', ariaLevel);
			li.setAttribute('role', 'treeitem');
			li.setAttribute('tabindex', '-1');
			li.down('a').setAttribute('tabindex', '-1');
			
			if (ariaLevel !== 1) {
				ul.setAttribute('role', 'group');
			}
			
			if (Element.hasClassName(trigger, 'active')) {
				li.setAttribute('tabindex', '0');
				li.setAttribute('aria-expanded', 'true');
				ul.setAttribute('role', 'tree');
			}
			
			Event.stopObserving(li, 'keydown');
			Event.observe(li, 'keydown', this.keyPressHandler.bindAsEventListener(this));
		}.bind(this));
		
		currentViewIndex = self.currentViewIndex();
		
		return self.getSelectedViewIdForHref_selectedViewAtIndex_andTriggerClassName_(window.location.href, currentViewIndex, triggerClassName);
	},
	
	didSetSwapView: function(self, view, triggerClassName) {
		var delegate = this;
		
		if (this._didShowNotificationListenerIsSet === false) {
			Event.Listener.listenForEvent(AC.ViewMaster, 'ViewMasterDidShowNotification', false, function(evt) {
				self.currentTrigger = (evt.event_data.data.trigger && !self.nextSelectedId && !Element.hasClassName(self.currentTrigger, 'browser-link')) ?
					evt.event_data.data.trigger :
					self.currentTrigger;

				var currentBrowserIndex = parseInt(self.currentViewIndex() + 1),
					sectionId = self.currentTrigger.href.split('#')[1],
					incomingView,
					incomingViewId,
					incomingTriggerClassName,
					foundBrowser,
					triggerIndex = false,
					triggerSpanText,
					minHeight,
					triggerList,
					selectedViewmaster = false,
					i = 0,
					section,
					hashValue = '',
					triggerId,
					triggerToScrollTo,
					viewmasters = self.viewmasters(),
					truncateCount = 30,
					entityMatchArr,
					entityLength = 0,
					heightToSet = '500px',
					triggerListMarginHeight,
					contentMarginHeight;
			
				if (self.currentTrigger.hasClassName(self.viewsToSet[0].triggerClassName)) {
					incomingViewId = sectionId + '-howto-content';
					incomingTriggerClassName = sectionId + '-howto-link';
					incomingView = $(incomingViewId);
					foundBrowser = self.viewsToSet.find(function(browser) {
						return (browser.view === incomingViewId) ? true : false;
					});

					if (!foundBrowser) {
						$$('.'+incomingTriggerClassName).each(function(trigger) {
							triggerSpanText = trigger.down('span').innerHTML;
							entityMatchArr = triggerSpanText.match(/&\w+;/g);
							entityLength = 0;
							if (entityMatchArr) {
								entityMatchArr.each(function(match) {
									entityLength += match.toString().length - 1;
								});
							}
							truncateCount = (entityLength > 0) ? parseInt(truncateCount + entityLength) : 30;
							trigger.down('span').innerHTML = triggerSpanText.truncate(truncateCount);
						});
					
						self.setView(sectionId, incomingViewId, incomingTriggerClassName);
						self.draw(currentBrowserIndex);

						triggerList = $$('.'+incomingTriggerClassName)[0].up('ul');
						minHeight = triggerList.getHeight();
						// added height for containing container for Safari 3
						triggerList.style.height = (minHeight > 500) ? minHeight + 'px' : '500px';
						triggerListMarginHeight = delegate.getMarginHeightFromElement(triggerList);
						contentMarginHeight = delegate.getMarginHeightFromElement(incomingView);
						triggerList.style.height = (minHeight > 500) ? minHeight + 'px' : '500px';
						incomingView.style.height = (minHeight > 500) ? ((minHeight + triggerListMarginHeight) - contentMarginHeight) + 'px' : ((500 + triggerListMarginHeight) - contentMarginHeight) + 'px';
						incomingView.up().style.height = (minHeight > 500) ? (minHeight + triggerListMarginHeight) + 'px' : (500 + triggerListMarginHeight) + 'px';
						
						incomingView.setAttribute('tabindex', '0');				
					} else if (this.nextSelectedId !== null) {
					
						while (selectedViewmaster === false && i < viewmasters.length) {
							selectedViewmaster = (viewmasters[i].id === sectionId) ? viewmasters[i] : false;
							i++;
						}
					
						section = selectedViewmaster.viewmaster.sectionWithId(this.nextSelectedId);
						this.nextSelectedId = null;

						selectedViewmaster.viewmaster.show(section, true);

					}
				} else {

					$$('.active.browser-selector-link').each(function(trigger, index) {
						Element.addClassName(trigger, 'visited');
						trigger.up('li').setAttribute('tabindex', '0');
				
						triggerId = trigger.href.split('#')[1];
				
						if (index === 0 && Element.hasClassName(trigger, 'nav-link')) {
							triggerToScrollTo = triggerId;
						} else hashValue += '.';
				
						hashValue += triggerId;
					});
			
					$$('.nav-link').each(function(trigger, index) {
						if (trigger.href.split('#')[1] === triggerToScrollTo) {
							triggerIndex = index;
						}
					});
			
					if (triggerIndex !== false) {
						slider.scrollToItem(triggerIndex);
						slider.resetPages();
					}
		
					document.location.hash = hashValue;
			
					var sectionContent = $$('.howto-browser')[0];
					var yOffset = sectionContent.viewportOffset()[1];
		            //if the content is above viewport to pretty far down the page bring it into view
		            if (yOffset < 0 || yOffset > (document.viewport.getHeight() * .75)) {
		                new Effect.ScrollTo(sectionContent, {duration: 0.3});
		            }
				}
			}.bindAsEventListener(self));
			
			this._didShowNotificationListenerIsSet = true;
		}
	},
	
	getMarginHeightFromElement: function(element) {
		return parseInt(element.getStyle('margin-top').split('px')[0]) + parseInt(element.getStyle('margin-bottom').split('px')[0]);
	}
});
