var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};

BrowserDetect.init();


var UI = { 
	testWindow: function() { 
		var options = {
			'yes': function(){ 
				alert('yes');
			},
			'no': function(){ 
				alert('no');
			},
			'ok': function() {
				alert('ok');
			},
			'cancel': function() {
				alert('cancel');
			}
		};
		UI.showMessage( { 
			'title': 'Title of Message',
			'message': 'Another line of text even though this is much longer. is it wrapping?<br />You can even make <a href="javascript:alert(\'test\');">a link</a> if you want.'
		}, options );
	},
	testLoadingWindow: function() {
		UI.showLoadingWindow('Please Wait');
	},
    settings: {
		blankImage: '/App_Themes/Default/img/blank.gif',
        closeButton: 'a.close',
		returnTrue: function(){ return true; },
		returnFalse: function(){ return false; },
		selectAll: 'input.selectAll',
		fadeDuration: 300,
		hiddenClass: 'hidden',
		selectedClass: 'selected',
		collectionClass: '.itemCollection',
		voidLink: 'javascript:Void();',
		toolTips: {
			className: '.toolTip',
			showDelay: 0,
			hideDelay: 500,
			fadeDelay: 500
		},
		tabs: {
			mainContainer: '.tabComponent',
			tabContainer: '.tabs',
			contentContainer: '.tabContent'
		},
		photoPager: {
			containerClass: '.slideShowDetails',
			backButtonElement: '#back a',
			forwardButtonElement: '#more a',
			thumbContainerId: 'thumbContainer',
			widthBoxId: 'widthbox',
			thumbnailGallery: 'thumbgall',
			//disableFlagHidEle: 'input.disablePager' 
			disableFlagHidEle: 'hfDisablePager'
		},		
		accordion: { 
			initialShowClass: 'showThisOne'
		},
		aspNetOptions: {
			mainTag: 'input[name=aspnet_js_option]'
		},
		characterCount: {
		    container: '.showCharacterCount',
		    counter: '.numberCharacterCount',
		    textField: '.inputCharacterCount',
		    customMaxLengthAttribute: 'maximumLength',
		    maxLength: 120
		},
		lightBox: { 
			containerId: 'lightbox',
			containerClass: 'lightboxContainer'
		},
		window: {
			loading: '0x00001'
		}
	},
	init: function() {
		UI.initTabs();
		UI.initAspNetOptions();
		UI.initThumbnailPager();
		UI.initToolTips();
		UI.initCharacterCount();
	},
	getPageTheme: function() { 
		var theBody = $(document.body);
		
		if( theBody.hasClass('greenTheme') ) {
			return 'green';
		} else if( theBody.hasClass('aquaTheme') ) {
			return 'aqua';
		} if( theBody.hasClass('purpleTheme') ) {
			return 'purple';
		} if( theBody.hasClass('orangeTheme') ) {
			return 'orange';
		}
		if( theBody.hasClass('blueTheme') ) {
			return 'blue'; 
		}
		
		return null;
	},
	/*
	 *
	 * showLightBox
	 *
	 */
	 showLightBox: function( theEle ) {
	 	 
		var lightBoxEle = $(UI.settings.lightBox.containerId);
		if( ! lightBoxEle ) {
			lightBoxEle = new Element( 'div', {
				'class': UI.settings.lightBox.containerClass + " " + UI.settings.hiddenClass,
				'id': UI.settings.lightBox.containerId
			});
			$(document.body).adopt( lightBoxEle );
		}
		
		var centerEle = function() { 
		   
			if( document.all ) {
                if(BrowserDetect.version>=7)
                {
				    var theWidth = theEle.offsetWidth;
				    var windowWidth = $(document.body).getSize().size.x;
				    if( ! theEle.hasClass('signIn') && ! theEle.hasClass('familyList') ) {
					    theEle.setStyle( 'left', -1 );
						theEle.setStyle( 'top', window.getScrollTop() + 20 );
				    }
				}
				else
				{
				    var theWidth = theEle.offsetWidth;
				    var windowWidth = $(document.body).getSize().size.x;
				    if( ! theEle.hasClass('signIn') && ! theEle.hasClass('familyList') ) {
					    theEle.setStyle( 'left', ((windowWidth - theWidth) / 2) );
					    if( window.ie6 ) {
						    theEle.setStyle( 'top', window.getScrollTop() + 20 );
					    }
				    }
				}
			}
			else
			{
			    if( theEle.hasClass('popLayer') ) 
			    {
			      theEle.setStyle( 'top', window.getScrollTop() + 20 );
			    }
			}
			
			var lightboxHeight = $(document.body).getSize().size.y + 20;
				if( lightboxHeight < window.getHeight() ) {
					lightboxHeight = window.getHeight();
				}
				lightBoxEle.setStyles({
					'width': '100%', // test.size.x,
					'height': lightboxHeight
				});		
		};
		
		window.addEvent('resize', centerEle );
		window.addEvent('scroll', centerEle );
		
		centerEle();
		
		lightBoxEle.removeClass( UI.settings.hiddenClass );
	},
	/*
	 *
	 *
	 */
	 hideLightBox: function( theEle ) {
		var lightBoxEle = $(UI.settings.lightBox.containerId);
		if( lightBoxEle ) {
			lightBoxEle.addClass( UI.settings.hiddenClass );	
		}
	},
	/* 
	 * addShowHideFunctionality() - adds Show/Hide Click event to an Element
	 * @params
	 *     ElementWithEvent - the Element that has the click event
	 *     ElementToActOn - the Element to Toggle
	 *     ClassToUse -  the class to apply
	 */
	addShowHideFunctionality: function(ElementWithEvent, ElementToActOn, ClassToUse) {    
	    ElementWithEvent.addEvent('click', function() {
	        ElementToActOn.toggleClass(ClassToUse);
	    });
	},
	/* 
	 * fadeInElement() - fades the element 'theEle' in (sets opacity from 0 to 1 in UI.settings.fadeDuration milliseconds
	 * @params
	 *     theEle - this is the main container ele, typically a window that will be faded in.
	 */
    fadeInElement: function( theEle, callback ) {
		var theFx = new Fx.Styles(theEle, {
			duration: UI.settings.fadeDuration, 
			wait: false,
			onComplete: function() {
				theEle.addClass('undoFixSelect');
				if( $type( callback ) == "function" ) { 
					callback();
				}
			}
		});
		theFx.set({'opacity': 0 });
		if( theEle.hasClass( 'positionHidden' ) ) {
		    theEle.__POSITION_HIDDEN = true;
		    theEle.removeClass( 'positionHidden' );
		} else {
		    theEle.removeClass( UI.settings.hiddenClass );
		}
		
		theFx.start({ 'opacity': 1 });
		$(document.body).addClass('fixSelect');

		UI.showLightBox( theEle );
	},
	/* 
	 * fadeOurElement() - fades the element 'theEle' our (sets opacity from 1 to 0 in UI.settings.fadeDuration milliseconds
	 * @params
	 *     theEle - this is the main container ele, typically a window that will be faded in.
	 */
	fadeOutElement: function( theEle, callback, lightBox ) {
		theEle.removeClass('undoFixSelect');
		var theFx = new Fx.Styles(theEle, { duration: UI.settings.fadeDuration, wait: false,
			onComplete: function() { 
	            if( theEle.__POSITION_HIDDEN ) { 
	                theEle.addClass( 'positionHidden' );
	            } else {
	                theEle.addClass( UI.settings.hiddenClass ); 
	            }
	            if( ! lightBox ) {
					UI.hideLightBox( theEle );
				}
				$(document.body).removeClass('fixSelect');
	            if( $type( callback ) == "function" ) {
	                callback();
	            }
			}
		});
		theFx.set({'opacity': 1 });
		theFx.start({ 'opacity': 0 });
	},
    /*
	 * initCloseButton() - generic close functionality, all it does is fade the window out and setup the link.
	 */
	initCloseButton: function( ele ) {
		try {
			var closeEle = ele.getElement( UI.settings.closeButton );
			closeEle.addEvent( 'click', function() {
				UI.fadeOutElement( ele );
			});
			closeEle.href = UI.settings.voidLink;		
		} catch( e ) {
			debug.log( Our365.errorMessages.genericMessage(e, 'close button: ele = "' + ele + '"' ) );
		}
		return closeEle;
	},
	/* initSelectAll() - checks all of the checkboxes in 'containerEle' depending on whether 'selectAllEle' is checked or not
	 * @params
	 *      containerEle - all the checkboxes in this container will have the same value as selectAllEle when it's checked.
	 *      value - will run selectAll instantly setting all checkboxes to 'value'
	 */
	initSelectAll: function( containerEle ) {
	    try {
	        
		    if( arguments.length > 1  ) {
			    UI.selectAll( containerEle, arguments[1] );
		    } else {
		        var selectAllEle = containerEle.getElement( UI.settings.selectAll );
		        selectAllEle.addEvent( 'click', function() {
                    UI.selectAll( containerEle.getElement(UI.settings.collectionClass), this.checked );
		        });
		    }
		} catch( e ) {
		    debug.log( Our365.errorMessages.genericMessage( e, 'UI.initSelectAll' ) );
		}
	},
	/*
	 * selectAll() - sets all 'selector.checked' items in parent to value
	 * @params
	 * 		HTMLElement parent - the container element for which to set
	 * 		String selector - a selector that's used to set the checked attribute, for example "input[type=checkbox]"
	 * 		bool value - the value to set checked
	 */
	selectAll: function( parent, value ) {
		try {
			var allEles = parent.getElements( 'input[type=checkbox]' );
			for( var i = 0; i < allEles.length; i++ ) {
				allEles[i].checked = value;
			}
		} catch( e ) {
			debug.log( Our365.errorMessages.genericMessage( e, 'UI.selectAll, if JS says "parent has no properties", then .selectAll[type=name] has the wrong value.' ) );
		}
	},
	initToolTips: function() {
		var toolTips = new Tips( $$(UI.settings.toolTips.className), {
			initialize:function(){
				this.fx = new Fx.Style(this.toolTip, 'opacity', {duration: 500, wait: false}).set(0);
			},
			onShow: function(toolTip) {
				this.fx.start(1);
			},
			onHide: function(toolTip) {
				this.fx.start(0);
			}
		});
	},
	/*
	 * getCheckedItems() - retrieves the 'value' of each of the checkboxes in 'parent' with each item wrapped in a container 'selector'
	 * @params -
	 *      HTMLElement parent - this is container element that has all the items.
	 *      String selector - this is a CSS selector that will distinguish what the individual item is in the container
	 *      Function itemCallBack - if a callback function is passed, then the callback will run prior to each item being added
	 *      	to the array. the item is bound to the callback (refer this), and checkbox.value is passed as an argument
	 *      	the idea of the callback is to parse an item (most likely HTML) and get data out of it.
	 */
	getCheckedItems: function( parent, selector, itemCallBack ) {
		var checkedEles = [];
		var eachEle = parent.getElements(selector);
		for( var i = 0; i < eachEle.length; i++ ) {
			var checkbox = eachEle[i].getElement('input[type=checkbox]');
			if( checkbox.checked ) {
				if( $type(itemCallBack) == 'function' ) {
					checkedEles.include( itemCallBack.bind( eachEle[i], [ checkbox.value ] )() );
				} else {
					checkedEles.include( checkbox.value );
				}
			}
		}
		return checkedEles;
	},
	initAspNetOptions: function() {
		var aspOptions = $$(UI.settings.aspNetOptions.mainTag);
		aspOptions.each(function(ele){
			var args = ele.value.split(";");
			switch( args[0] ){ 
				case 'hideParentEle':
					for(var i=1;i<args.length;i++) {
					    var goBackEle = ele.parentNode;
					    var notFound = false;
					    if( args[i] ) {
					        var count = 0;
						    while( goBackEle.tagName.toLowerCase() != args[i].toLowerCase() ) {
						        if(count < 2) {
							        goBackEle = goBackEle.parentNode;
							        count++;
							    }else {
							        notFound = true;
							        break;
							    }
						    }
					    }
					    if( goBackEle != document && notFound == false) {
						    $(goBackEle).addClass(UI.settings.hiddenClass);
						    break;
					    }
					}
					break;
			}
		});

	},
	showMessage: function( message, options ) {
		var newWindow = HTMLFactory.createGenericWindow( message, options );
		newWindow.addClass( UI.settings.hiddenClass );
		$(document.body).adopt( newWindow );
		UI.initCloseButton(newWindow);
		var callback;
		if( arguments.length > 2 ) {
			callback = arguments[2];
		}
		UI.fadeInElement(newWindow,callback);
	},
	showLoadingWindow: function(str, callback ) {
		UI.showMessage( str, UI.settings.window.loading, callback );
	},
	initTabs: function() {
		// there can be more than 1 tabComponent object on a page.
		var tabObjs = $$(UI.settings.tabs.mainContainer);
		
		// check to see if there is at least 1 'tabComponent' on the page
		if( tabObjs.length > 0 ) {
			try {
				tabObjs.each( function(tabObj){
					var tabContainer = tabObj.getElement(UI.settings.tabs.tabContainer);
					var tabContentContainer = tabObj.getElement(UI.settings.tabs.contentContainer);
					
					if( tabContainer && tabContentContainer ) {
						var tabContentEles = tabContentContainer.getElements("li");
						var tabEles = tabContainer.getElements("li");
						
						// integrity test
						if( tabEles.length != tabContentEles.length ) {
							throw 'integrity check failed, the amount of tabs and tab contents do not match';
						}
						
						// find current selected tab
						var initialSelected = 0;
						tabEles.each(function(item,index){ if( item.hasClass( UI.settings.selectedClass ) ) { initialSelected = index; } });
						tabObj.active = initialSelected;
						
						// set events on the tabs.
						tabEles.getElements('a').each(function(item,index){
							item.href = UI.settings.voidLink;
							item.addEvent( 'click', function(){
								this.blur();
								// turn tab off
								for(var i=0;i<tabEles.length;i++) {
								    //alert("yo");
								    tabEles[ i ].removeClass(UI.settings.selectedClass);
								    tabContentEles[ i ].removeClass(UI.settings.selectedClass);
								}
								// turn tab on
								tabEles[ index ].addClass(UI.settings.selectedClass);
								tabContentEles[ index ].addClass(UI.settings.selectedClass);
								tabObj.active = index;
							});
						});
					}
				});
			} catch( e ) {
				debug.log( UI.errorMessages.tabComponent(e) );
			}
		}
	},
	initCharacterCount: function() {
	    var containerEles = $$(UI.settings.characterCount.container);
	    containerEles.each(function(item){
	        var counterEle = item.getElement(UI.settings.characterCount.counter);
	        var inputFieldEle = item.getElement(UI.settings.characterCount.textField);
	        
	        var handleCharacterCount = function() {
	            var maxLength = UI.settings.characterCount.maxLength;
	            if( inputFieldEle.getAttribute(UI.settings.characterCount.customMaxLengthAttribute) ) {
	                maxLength = inputFieldEle.getAttribute(UI.settings.characterCount.customMaxLengthAttribute);
	            }
	            
	            if( this.value.length <= maxLength)  {
	                if( counterEle ) {
						counterEle.setText(maxLength - this.value.length);
	                }
	            } else {
	                this.value = this.value.substr(0, maxLength);
	                if( counterEle ) {
						counterEle.setText('0');
	                }
	            }
	        }
	        
	        inputFieldEle.addEvent('keyup', handleCharacterCount );
	        handleCharacterCount.bind( inputFieldEle )();
	    });
	},
	fadeOutAndRemove: function(theEle) {
		var theFx = new Fx.Styles(theEle, { duration: 1000, wait: false,
			onComplete: function() { 
		         theEle.remove();
			}
		});
		theFx.set({'opacity': 1 });
		theFx.start({ 'opacity': 0 });
	},
	initThumbnailPager: function() {
		var pagerEles = $$(UI.settings.photoPager.containerClass);		
		//added to disable pager if needed for photos/slideshow		
        var disablePagerEle = $(UI.settings.photoPager.disableFlagHidEle);
	    if ( $defined(disablePagerEle) ) {
	        if (disablePagerEle.value == "true")
	            return;
	    }
		pagerEles.each(function(item){
			try {
				var backEle = item.getElement(UI.settings.photoPager.backButtonElement);
				var forwardEle = item.getElement(UI.settings.photoPager.forwardButtonElement);
				var photoContainerEle = $(UI.settings.photoPager.thumbContainerId);
				var photoCollectionEle = $(UI.settings.photoPager.thumbnailGallery);
				var photoEles = $(UI.settings.photoPager.thumbContainerId).getElements("a");
				var slideAnimation = new Fx.Styles( photoCollectionEle, {duration: 150, transition: Fx.Transitions.linear});
				var currentLeft = 0;
				imageWidth = photoEles[0].getSize().size.x;
				forwardEle.addEvent( 'click', function() {
					var offset = photoCollectionEle.getSize().size.x - photoContainerEle.getSize().size.x;
					if( ( currentLeft * -1 ) < offset ) {
						currentLeft -= imageWidth;
						slideAnimation.start( {'left' : currentLeft } );
						photoCollectionEle.setStyle('left', currentLeft );
						this.blur();
						backEle.removeClass('hidden');
					}
					if( ( currentLeft * -1 ) >= offset ) {
						forwardEle.addClass('hidden');
					}
				});
				
				var offset = photoCollectionEle.getSize().size.x - photoContainerEle.getSize().size.x;
				if( ( currentLeft * -1 ) >= offset ) {
					forwardEle.addClass('hidden');
				}
				
				forwardEle.href = UI.settings.voidLink;
				backEle.addClass('hidden');
				backEle.addEvent( 'click', function() {
					if( currentLeft < 0 ) {
						currentLeft += imageWidth;
						slideAnimation.start( {'left' : currentLeft } );
						this.blur();
						forwardEle.removeClass('hidden');
					}
					
					if( currentLeft >= 0 ) {
						backEle.addClass('hidden');
					}
				});
				backEle.href = UI.settings.voidLink;
			} catch( e ) {
				debug.log( UI.errorMessages.thumbnailPager(e) );
			}
		});
	},
	addSelectedClass: function() {

	},
	initAccordion: function( parent, eventSelector, contentSelector ) {
		var selectedIndex = 0;
		parent.getElements(contentSelector).each( function(item,index){ if( item.hasClass(UI.settings.accordion.initialShowClass) ) { selectedIndex = index; } });
		var accordion = new Accordion( eventSelector, contentSelector, {
			opacity: false,
			display: selectedIndex,
			onActive: function(toggler, element){
				Element.addClass( toggler, 'selected' );
			},
			onBackground: function(toggler, element){
				Element.removeClass( toggler, 'selected' );
			}
		}, parent);
	},
	errorMessages: {
		tabComponent: function( e ) {
			return( "[ERROR] 'tabComoponent' threw an exception.\njavascript says '" + e + "'" );
		},
		thumbnailPager: function( e ) {
			return( "[ERROR] 'initThumbnailPager' threw an exception.\njavascript says '" + e + "'" );
		}
	},
	/*
	 * startDebugger() - this will force the debugger to open
	 */
    startDebugger: function() {
        debug.create();
    }
};