function OfferConfigurator()
{
	var self = this;
	
	this.pixels_per_page = 460;
	
	var menu_button_src_normal = '/shop/gfx/conf_suggest_settings.png';
	var menu_button_src_active = '/shop/gfx/conf_suggest_settings_active.png';
	
	this.scrollToPrevPage = function( entry_type, index )
	{
		if ( _getCurrentPageNr( entry_type, index ) == 0 )
			return;
		
		_getOuterContainer(entry_type, index).find('[class^="conf_suggest_arrow_left"]').unbind();
	
		_scrollToPage(entry_type, index, _getCurrentPageNr( entry_type, index ) - 1);
	}
	
	this.scrollToNextPage = function( entry_type, index )
	{
		if ( _getCurrentPageNr(entry_type, index) + 1 >= _getNumberOfPages(entry_type, index) )
			return;
		
		_getOuterContainer(entry_type, index).find('[class^="conf_suggest_arrow_right"]').unbind();
		
		_scrollToPage( entry_type, index, _getCurrentPageNr( entry_type, index ) + 1 );
	}
	
	this.pageLoaded = function()
	{
		// Update Price
		var total_price = ajax.call( 'OfferConfiguratorController::fetchTotalPrice', [] );
		var button_img_src = $('.basket_button:first').attr('src').match(/^(\/shop\/gfx\/b_warenkorb(?:_update)?)(_disabled)?\.gif$/)[1];
		button_img_src += total_price.match(/[-0-9]+,[-0-9]{2}/) ? '.gif' : '_disabled.gif';
		
		$('.total_price').html( total_price );
		$('.basket_button').attr('src', button_img_src );
		
		// Hinweis bei negativem Betrag
		var total_price_text = $('.total_price:first').html();
		
		var total_price = total_price_text.match(/-?[0-9]+,[-0-9]{2}/);
		
		var negative_hint = total_price && total_price_text.match(/-[0-9]+,[-0-9]{2}/) ? 
			'Der negative Betrag wird Ihnen erstattet!' :
			'';
		$('.negative_hint').html(negative_hint);
		
		$('.contract_send_back_date').fadeTo('fast', total_price ? 1 : .3);
		
		// Pfeile aktualisieren
		var reg_pattern = /^box_(.*)/;
		$('[id^=box_]').each( function(){
			
			var box = this;
			var entry_type = this.id.match(/^box_(.*)/)[1];
			
			$(this).find('[id^="entry_suggestions_' + entry_type + '_"]').each(function(){
				
				var index = this.id.match(/^entry_suggestions_[^_]+_([0-9])/)[1];
				
				_loadEntryMenu( entry_type, index);
				
				setTimeout(function() { 
					_updateSuggestionsPages( entry_type, index );
				}, 500);
			});
		});
		
		setTimeout(function() {
		
			if ($('.entry_details').length > 1 && $(window).scrollTop() > 85)
			{
				var windowSize = [$(window).width(), $(window).height()];
				
				var xPos = windowSize[0] / 2 - 100;
				var yPos = Math.max( 40, windowSize[1] / 2 - 60 );
				
				var price_overlay = $( '<div id="price_overlay">Aktueller Gesamtpreis: ' + total_price + ' EURO</div>' );
				
				price_overlay.css({position:'fixed', padding:'5px 20px', 
					background:'white', color:'black', fontWeight:'bold',
					display:'block', left:xPos, top:yPos, fontSize:16, zIndex:10,
					MozBorderRadius:8, WebkitBorderRadius:8, border:'3px solid #3392bc',
					WebkitBoxShadow:'1px 1px 3px rgba(0,0,0,.5)', MozBoxShadow:'3px 3px 3px black' });
				
				if ( $.browser.msie )
				{
					price_overlay.css({position:'absolute'});
					xPos += $(window).scrollLeft();
					yPos += $(window).scrollTop();
				}
				
				price_overlay.css({left:xPos, top:yPos});
				$('body').append(price_overlay);
				
				setTimeout(function(){ price_overlay.fadeOut('normal'); }, 3500 );
			}
		}, 200);
	}
	
	this.preloadImages = function()
	{
		$( ['/shop/gfx/conf_suggest_arrow_left.png',
			'/shop/gfx/conf_suggest_arrow_left_hover.png',
			'/shop/gfx/conf_suggest_arrow_left_active.png',
			'/shop/gfx/conf_suggest_arrow_left_disabled.png',
			'/shop/gfx/conf_suggest_arrow_right.png',
			'/shop/gfx/conf_suggest_arrow_right_hover.png',
			'/shop/gfx/conf_suggest_arrow_right_active.png',
			'/shop/gfx/conf_suggest_arrow_right_disabled.png',
			'/shop/gfx/b_warenkorb.gif',
			'/shop/gfx/b_warenkorb_update.gif',
			'/shop/gfx/b_warenkorb_disabled.gif',
			'/shop/gfx/b_warenkorb_update_disabled.gif',
			'/gfx/wait_black.gif',
			menu_button_src_active] ).each( function()
			{
				var img = new Image()
				img.src = this;
			});
	}
	
	this.showSpinner = function()
	{
		$('#configurator .box').fadeTo( 'fast', 0.5);
		
		windowSize = [$(window).width(), $(window).height()];
		
		var xPos = windowSize[0] / 2 + 30;
		var yPos = Math.max( 40, windowSize[1] / 2 - 60 );
		
		$('body').append('<div id="spinner"><img src="/gfx/wait_black.gif" alt="Loading..." /></div>');
		if ( $.browser.msie )
		{
			$('#spinner').css({position:'absolute'});
			xPos += $(window).scrollLeft();
			yPos += $(window).scrollTop();
		}
		
		$('#spinner').css({opacity:1.0, display:'block', left:xPos, top:yPos});
		
		this.hideTooltip();
	}
	
	this.hideSpinner = function()
	{
		$('#spinner').fadeTo('normal', 0, function() { $(this).remove() });
	}
	
	this.reloadConfigurator = function()
	{
		ajax.call( 'OfferConfiguratorController::fetch', [], function(output){
			
			self.hideSpinner();
			$('#configurator').html(output);
			
			self.pageLoaded();
		});
	}
	
	this.getMousePos = function(event)
	{
		if ( !event )
			event = window.event;
		
		if (event.pageX || event.pageY)
			return [event.pageX, event.pageY];
		
		if (event.clientX || event.clientY)
			return [event.clientX + $(window).scrollLeft(), event.clientY + $(window).scrollTop()];
		
		return [];
	}
	
	var tooltipCounter = 0;
	
	this.showTooltip = function( text, event )
	{
		if ( $('#spinner').length > 0 )
			return;
	
		var div = $('.tooltip');
		
		if (!div.length) {
			div = $('<div class="tooltip"></div>');
			$('body').append(div);
		}
		
		var mouse_pos = this.getMousePos(event);
		div.css({position:'absolute', zIndex:1, display:'none', opacity:1 });
		this.moveTooltip( event );
		div.html(text);
		
		tooltipCounter++;
		div.stop().fadeIn('fast');
	}
	
	this.moveTooltip = function( event )
	{
		var mouse_pos = this.getMousePos(event);
		$('.tooltip').css({left:mouse_pos[0] - 80, top:mouse_pos[1] + 30 });
	}
	
	this.hideTooltip = function()
	{
		tooltipCounter--;
		$('.tooltip').fadeOut('fast');
	}
	
	function _scrollToPage( entry_type, index, page_nr )
	{
		var container_div = _getPagesContainer( entry_type, index );
		
		container_div.animate({left:'' + ( -self.pixels_per_page * page_nr ) + 'px'},
							  600,
							  function() {
								  setTimeout(function() { 
									  _updateSuggestionsPages( entry_type, index );
								  }, 0);
							  } );
	}
	
	function _getCurrentPageNr( entry_type, index )
	{
		var container_div = _getPagesContainer( entry_type, index );
		
		return - parseInt( container_div.css('left') ) / self.pixels_per_page;
	}
	
	function _getNumberOfPages( entry_type, index )
	{
		return _getPagesContainer( entry_type, index ).find('.suggestions_page').length;
	}
	
	function _getOuterContainer( entry_type, index )
	{
		return $('#entry_suggestions_' + entry_type + '_' + index);
	}
	
	function _getPagesContainer( entry_type, index )
	{
		return _getOuterContainer(entry_type, index).find('.suggestions_pages');
	}

	function _updateSuggestionsPages(entry_type, index)
	{
		// Left arrow
		var arrow = _getOuterContainer(entry_type, index).find('[class^="conf_suggest_arrow_left"]');
		arrow.unbind();
		
		var current_page_nr = _getCurrentPageNr(entry_type, index);
		
		if ( current_page_nr > 0 ) {
			
			arrow
			
			.click( function(){
				self.scrollToPrevPage( entry_type, index );
				})
			
			.attr('class', 'conf_suggest_arrow_left');
		}
		else {
			
			arrow
			
			.attr('class', 'conf_suggest_arrow_left_disabled');
		}

		// Load more entries for view mode "list"
		if ( _getNumberOfPages(entry_type, index) == 0 ) {

			oc.loadListEntries( entry_type, index, 1 );

		}

		// Preload next page in view mode "images"
		else {
			if ( _getCurrentPageNr(entry_type, index) + 2 >= _getNumberOfPages(entry_type, index) )
			{
				_getPagesContainer( entry_type, index ).append(
					ajax.call('OfferConfiguratorController::fetchSuggestionsPage', [entry_type, index, _getNumberOfPages(entry_type, index)] ) );
			}
		}
		
		// Right arrow
		arrow = _getOuterContainer(entry_type, index).find('[class^="conf_suggest_arrow_right"]');
		arrow.unbind();
		
		var number_of_pages = _getNumberOfPages(entry_type, index);
		
		// Right arrow
		if ( current_page_nr + 1 < number_of_pages ) {
			
			arrow
			
			.click( function(){
				self.scrollToNextPage( entry_type, index );
				})
			
			.attr('class', 'conf_suggest_arrow_right');
		}
		else {
			
			arrow
			
			.attr('class', 'conf_suggest_arrow_right_disabled');
		}
	}
	
	function _loadEntryMenu( entry_type, index ) {
		
		ajax.call('OfferConfiguratorController::getSettingsMenuForEntryType', [entry_type], function(content) {
			
			var menu_button = $('<img src="/shop/gfx/conf_suggest_settings.png" class="entry_menu_button" alt="Menü" />');
								
			var menu = $('<div class="entry_menu"></div>');
			
			menu.hide()
				.mousedown( function(event){ return false } )
				.html( content );
			
			$('#configurator').append(menu);
	
			$(menu_button).mousedown( function() {
				
				if ( menu.css('display')=='block' ) {
					self.hideEntryTypeMenus();
				}
				else {
					
					$(this).one('mouseup', function() {
						$('body').one('mousedown', function(event){ oc.hideEntryTypeMenus() } );
					});
					
					oc.hideEntryTypeMenus();
					
					menu.css( {	 top: $(menu_button).offset().top + $(menu_button).height(),
								left: $(menu_button).offset().left - menu.width() + $(menu_button).width() - 1
							} );
									
					if ( $.browser.msie ) {
						menu.css({ background:'#fbfbfb' });
					}
					
					menu.show();
					
					menu_button.attr('src', menu_button_src_active);
				}
				
				return false;
			} );
			
			$('#box_' + entry_type).find('.entry_navi_table:eq('+index+') > tbody > tr > td:eq(1)' ).append(menu_button);
		});
	}
	
	this.hideEntryTypeMenus = function() {
		$('#configurator .entry_menu').fadeOut('fast');
		$('#configurator .entry_menu_button').attr('src', menu_button_src_normal);
	}
	
	this.setSortOrderForEntryType = function ( entry_type, order ) {
		this.hideEntryTypeMenus();
		this.call('setSortOrderForEntryType', [entry_type, order]);
	}
	
	this.setProductsViewForEntryType = function ( entry_type, view ) {
		this.hideEntryTypeMenus();
		this.call('setProductsViewForEntryType', [entry_type, view]);
	}
	
	this.call = function( method, args ) {
		this.showSpinner();
		ajax.call('OfferConfiguratorController::'+method, args, function(){ self.reloadConfigurator() } );
	}

	this.loadListEntries = function ( entry_type, index ) {

		var entries_per_page = 64;
		
		var outer = $('#entry_suggestions_' + entry_type + '_' + index + ' div.conf_view_list_body');
		var container = outer.find('table');

		while ( container.height() < outer.scrollTop() + outer.height() ) {
			
			if ( container.find('tr').length % entries_per_page )
				return;
			
			var page = container.find('tr').length / entries_per_page;

			var content = ajax.call('OfferConfiguratorController::fetchSuggestionsPage', [entry_type, index, page]);

			if ( !content )
				return;
			
			container.append( content );
		}
	}
	
	this.pageLoaded();
	this.preloadImages();
}

$( function() {
	oc = new OfferConfigurator();
});
