

// These counter indexes are reserved
var COUNTER_NUMSEATS = 0;
var COUNTER_AVAILABLESEATS = 1;
var COUNTER_FILTEREDSEATS = 2;

//A price category counter index is priceCatNumber + COUNTER_OFFSET
var COUNTER_OFFSET = 2;



var STATUS_NOTAVAILABLE			= '0';
var STATUS_AVAILABLE			= '1';
var STATUS_FILTEREDAVAILABLE	= '3';


// Colors
var COLOR_WHITE				= '0xFFFFFF';
var COLOR_AVAILABLE			= '0x1D5D91';
var COLOR_NOTAVAILABLE		= '0x999999';
var COLOR_FILTEREDAVAILABLE = '0x001D47';
var COLOR_SELECTED 			= '0xEF6307';

var LEGEND_PRIORITY = 2;


var SvlDynamic = Class.create({
	
	initialize: function(eventObj) {
		this.eventInfo = eventObj;
		this.priceCats = eventObj.prices.priceCategory;
		this.priceCatsNum = eventObj.prices.priceCategory.size();
	},

	setDebugMode: function(debug) {
		this.debug = debug;
	},
	
	
	getSvlScriptFilter: function(selectedFilters) {
		var filterCode = "";
		var filterPolyCode = "";
		
		// filter with run_time_flags for selected filters for available and also available seats
		selectedFilters.each(function(s){
			filterPolyCode += '(seat.run_time_flags) == '+this.getStatusValue(s, STATUS_FILTEREDAVAILABLE)+':set graphic.counter_deltas['+COUNTER_FILTEREDSEATS+']=1;';
			filterCode += '(seat.run_time_flags) == '+this.getStatusValue(s, STATUS_AVAILABLE)+' && (seat.seat_flags) == 0:run_defined_seat_encoders("available_filter_encoders");';
		}.bind(this));
		
		//Shade Seat
		var shade_seat = '1:run_defined_seat_encoders("seat_class_encoders");'+ // set all run_time flags to not available
					 	 filterCode +	// seats that matches selected filter set run_time flags
					 	 '1:run_defined_seat_template_selectors("modified_match_selectors");' + //connect with seat_templates
					 	 '(seat.seat_flags) == 0 && (seat.base_type) == 0:set graphic.counter_deltas['+COUNTER_AVAILABLESEATS+']=1;'+  
					 	 filterPolyCode + // num of available seats
					 	 '1:set graphic.counter_deltas['+COUNTER_NUMSEATS+']=1;'; 


		for (var i = 0; i<this.priceCatsNum; i++){
			var priceCatNumber = this.priceCats[i].number;
			shade_seat = shade_seat + '(seat.run_time_flags == '+this.getStatusValue(priceCatNumber, STATUS_FILTEREDAVAILABLE)+' || seat.run_time_flags == '+this.getStatusValue(priceCatNumber, STATUS_AVAILABLE)+'):set graphic.counter_deltas['+(priceCatNumber+COUNTER_OFFSET)+']=1;';
		}
		
		var shadeSeat = 
		{
			"procedure_point" :  "shade_seat",	
			"script" : shade_seat		
		};
		
		
		//select what polygon template to use
		var shade_polygon = '1:select_polygon_template("POLYGON_NOT_AVAILABLE");' + 
				 			'polygon.counters['+COUNTER_AVAILABLESEATS+'] != 0:select_polygon_template("POLYGON_AVAILABLE");'+
				 			'polygon.counters['+COUNTER_FILTEREDSEATS+'] != 0:select_polygon_template("POLYGON_FILTERED_AVAILABLE");';
		
		var shadePolygon = 
		{
				"procedure_point": "shade_polygon",
				"script": shade_polygon
		};
		
		var svl = [];
		svl.push(shadeSeat);
		svl.push(shadePolygon);

		return Object.toJSON(svl);
	},
	
	//Standard SVLData, Sent to the widget on init. This contains all Templates and all encoders
	getSvlData: function(selectedFilters) {
		var svl = 
		{
			"polygon_shading_template_hash" : this.getPolygonShadingTemplateHash(selectedFilters),
			"seat_shading_template_hash" : this.getSeatShadingTemplateHash(selectedFilters),
			"seat_condition_encoder_hash" : this.getSeatConditionEncoderHash(),
			"seat_template_selector_hash" : this.getSeatTemplateSelectorHash()
		};
		
		return Object.toJSON(svl);
	},
	
	
	//Templates for Seats
	getSeatShadingTemplateHash: function(selectedFilters) {
		var debug = '';
		if (this.debug) {
			debug = 
				 "<span class='textBlack'><br/><br/><b>debug:</b>"
				+"<br/>base_type:[% @1:(seat.base_type); %]"
				+"<br/>seat_flags:[% @1:(seat.seat_flags); %]"
				+"<br/>run_time_flags:[% @1:(seat.run_time_flags); %]"
				+"</span>";
		}		
		
		var orange_seat_name = '<span class=\'textOrangeBold\'>'+TU('SECTION')+' [% section %], '+TU('ROW')+' [% row %], '+TU('SEAT')+' [% seat %]</span><br/>';
		var gray_seat_name = '<span class=\'textGray\'>'+TU('SECTION')+' [% section %], '+TU('ROW')+' [% row %], '+TU('SEAT')+' [% seat %]</span><br/>';
		
		var price_tool_tip_template = '';
		for (var i = 0; i<this.priceCatsNum; i++){
			var priceCatNumber = this.priceCats[i].number;
			price_tool_tip_template += "[% @(seat.run_time_flags) == "+this.getStatusValue(priceCatNumber,STATUS_AVAILABLE)+":\"";
			price_tool_tip_template += "<span class='textBlack'>";
			price_tool_tip_template += this.getPriceCategoryToolTip(priceCatNumber) +"</span>\"; %]";

			price_tool_tip_template += "[% @(seat.run_time_flags) == "+this.getStatusValue(priceCatNumber,STATUS_FILTEREDAVAILABLE)+":\"";
			price_tool_tip_template += "<span class='textBlackBold'>";
			price_tool_tip_template += this.getPriceCategoryToolTip(priceCatNumber) +"</span>\"; %]";
		}
		
		var SEAT_AVAILABLE =
		{
			"background_color" : COLOR_AVAILABLE,
			"border_color" : COLOR_WHITE,
			"selectable" : true,
			"legend_text" : TU('ALSO_AVAILABLE'),
			"show_in_legend_always": true,
			"legend_tool_tip_html" : "<span class='textBlack'>"+TU('ALSO_AVAILABLE_LEGEND_TOOLTIP')+"</span",
			"legend_priority" : 3,
			"tool_tip_template" : orange_seat_name + price_tool_tip_template + debug
		};
		
		var SEAT_NOT_AVAILABLE = 
		{
			"background_color" : COLOR_NOTAVAILABLE,
			"border_color" : COLOR_WHITE,
			"selectable" : false,
			"legend_text" : TU('NOT_AVAILABLE'),
			"show_in_legend_always": true,
			"legend_priority" : 4,
			"legend_tool_tip_html" : "<span class='textBlack'>"+TU('NOT_AVAILABLE_TOOLTIP_SEAT_LEVEL')+"</span",
			"tool_tip_template" : gray_seat_name + debug		
		};
			
		var SEAT_FILTERED_AVAILABLE =
		{
			"background_color" : COLOR_FILTEREDAVAILABLE,
			"border_color" : COLOR_WHITE,
			"selectable" : true,
			"legend_text" : TU('MATCHES_YOUR_SEARCH'),
			"show_in_legend_always": true,
			"legend_tool_tip_html" : "<span class='textBlack'>"+TU('MATCHES_YOUR_SEARCH_TOOLTIP')+"</span",
			"legend_priority" : 2,
			"tool_tip_template" : orange_seat_name + price_tool_tip_template + debug
		};
		
		var SELECTED =
		{
			"background_color" : COLOR_SELECTED,
			"border_color" : COLOR_WHITE,
			"selectable" : true,
			"legend_text" : TU("YOUR_SELECTED_SEATS"),
			"show_in_legend_always": true,
			"legend_tool_tip_html" : "<span class='textBlack'>"+TU('YOUR_SELECTED_SEATS_LEGEND_TOOLTIP')+"</span",
			"legend_priority" : 1,
			"tool_tip_template" : orange_seat_name + price_tool_tip_template + debug
		};
		
		var AVAILABLE = {
			show_in_legend_always : false
		};
		
		var UNAVAILABLE = {
			show_in_legend_always : false 	
		};
		
		var ALSO_AVAILABLE = {
			show_in_legend_always : false	
		};
		
		var AVAILABLE_NO_MATCH = 
		{
			"background_color" : COLOR_AVAILABLE,
			"border_color" : COLOR_WHITE,
			"selectable" : true,
			"legend_text" : "Also available",
			"legend_priority" : 3,
			"tool_tip_template" : orange_seat_name + price_tool_tip_template + debug
		};
		
		
		var svl = 
		{
			"SEAT_AVAILABLE": SEAT_AVAILABLE,
			"SEAT_NOT_AVAILABLE": SEAT_NOT_AVAILABLE,
			"SEAT_FILTERED_AVAILABLE": SEAT_FILTERED_AVAILABLE,
			"AVAILABLE": AVAILABLE,
			"UNAVAILABLE": UNAVAILABLE,
			"SELECTED": SELECTED,
			"ALSO_AVAILABLE": ALSO_AVAILABLE
		};
		
		return svl;
	},
	
	
	// Templates for polygons
	getPolygonShadingTemplateHash: function(selectedFilters) {
		
		var debug = '';
		if (this.debug) {
			debug = "<span class='textBlack'><br/><br/>debug"
				+"<br/>is_ga:[% @1:(polygon.is_ga); %]"
				+"<br/>is_single_seats_only:[% @1:(polygon.is_single_seats_only); %]"
				+"<br/>section_list:[% @1:(polygon.section_list); %]"
				+"<br/>counters["+COUNTER_NUMSEATS+"](Seats total):[% @1:(polygon.counters["+COUNTER_NUMSEATS+"]); %]"
				+"<br/>counters["+COUNTER_AVAILABLESEATS+"](Available Seats):[% @1:(polygon.counters["+COUNTER_AVAILABLESEATS+"]); %]"
				+"<br/>counters["+COUNTER_FILTEREDSEATS+"](Also Available Seats):[% @1:(polygon.counters["+COUNTER_FILTEREDSEATS+"]); %]";
			for (i = 1; i <= 7; i++) {
				debug += "<br/>counters["+(i+COUNTER_OFFSET)+"](Total Seats in cat "+i+"):[% @1:(polygon.counters["+(i+COUNTER_OFFSET)+"]); %]"
				
			}
			debug += "</span>";
		}

		var if_is_ga_only = "[% @(polygon.is_ga) ==1:\"<span class='textBlackBoldItalic'>"+TU('GENERAL_ADMISSION_ONLY')+"</span><br>\"; %]"; 
		if(this.eventInfo.mksVal==1){
			if_is_ga_only = "";
		}
		var orange_section_name = "<span class='textOrangeBold'>[% section_name %]<br/></span>";
		var gray_section_name = "<span class='textGray'>[% section_name %]<br/></span>";
		
		var no_seats = "<span class='textBlackBoldItalic'>"+TU('NO_SEATS_AVAILABLE')+"</span><br/>";
		
		var price_tool_tip_template = '';
		// Add all prices
		for (var i = 0; i<this.priceCatsNum; i++){
			var priceCatNumber = this.priceCats[i].number;
			selected = false;
			for (var j = 0; j <= selectedFilters.length; j++) {
				if (selectedFilters[j] == priceCatNumber) {
					selected = true;
					break;
				}
			}
			
			price_tool_tip_template += "[% @(polygon.counters["+(priceCatNumber+COUNTER_OFFSET)+"]) != 0:\"<br/>";
			if (selected) {
				price_tool_tip_template += "<span class='textBlackBold'>";
			} else {
				price_tool_tip_template += "<span class='textBlack'>";
			}
			price_tool_tip_template += this.getPriceCategoryToolTip(priceCatNumber) +"</span>\"; %]";	
		}
		
		var POLYGON_AVAILABLE = 
		{
			"interior": COLOR_AVAILABLE,
			"border": COLOR_WHITE,
			"legend_text" : " "+TU('ALSO_AVAILABLE')+ " ",
			"legend_tool_tip_html" : "<span class='textBlack'>"+TU('ALSO_AVAILABLE_LEGEND_TOOLTIP')+"</span",
			"show_in_legend_always": true,
			"legend_priority" : 2,
			"poly_tool_tip_template": if_is_ga_only + orange_section_name + price_tool_tip_template + debug
		};
		
		var POLYGON_NOT_AVAILABLE = 
		{
			"interior": COLOR_NOTAVAILABLE,
			"border": COLOR_WHITE,
			"legend_text" : " "+TU('NOT_AVAILABLE')+" ",
			"show_in_legend_always": true,
			"legend_tool_tip_html" : "<span class='textBlack'>"+TU('NOT_AVAILABLE_LEGEND_TOOLTIP')+"</span",
			"legend_priority" : 3,
			"poly_tool_tip_template": if_is_ga_only + no_seats + gray_section_name + price_tool_tip_template + debug
		};
		
		var POLYGON_FILTERED_AVAILABLE = 
		{
			"interior": COLOR_FILTEREDAVAILABLE,
			"border": COLOR_WHITE,
			"legend_text" : " "+TU('AVAILABLE')+" ",
			"legend_tool_tip_html" : "<span class='textBlack'>"+TU('AVAILABLE_LEGEND_TOOLTIP')+"</span",
			"show_in_legend_always": true,
			"legend_priority" : 1,
			"poly_tool_tip_template": if_is_ga_only + orange_section_name + price_tool_tip_template + debug
		};
		
		var HIDE = {
				show_in_legend_always : false,
				"legend_priority" : 5
		};
			

		
		if(this.eventInfo.mksVal==1){	
			POLYGON_AVAILABLE["action"] = 'ga';
			POLYGON_AVAILABLE["ga_sect"] = 'overview';
			POLYGON_NOT_AVAILABLE["action"] = 'ga';
			POLYGON_FILTERED_AVAILABLE["action"] = 'ga';
			POLYGON_FILTERED_AVAILABLE["ga_sect"] = 'overview';
		}	
		var svl = 
		{
			POLYGON_AVAILABLE: POLYGON_AVAILABLE,
			POLYGON_NOT_AVAILABLE: POLYGON_NOT_AVAILABLE,
			POLYGON_FILTERED_AVAILABLE: POLYGON_FILTERED_AVAILABLE,
			AVAILABLE_4_HIGH: HIDE,
			AVAILABLE_4_MEDIUM: HIDE,
			AVAILABLE_4_LOW: HIDE,
			AVAILABLE_4_NONE: HIDE
		};

		return svl;
	},
	
	getSeatConditionEncoderHash: function() {
		
		var priceCats = this.eventInfo.prices.priceCategory;
		var priceCatsNum =  priceCats.size();
		
		var seat_class_encoders = [];
		var not_available_filter_encoders = [];
		var also_available_filter_encoders = [];
		var available_filter_encoders = [];
		
		var tmol_matches_encoders = [];
		
		
		for (var i = 0; i< this.priceCatsNum; i++){
			var priceCatNumber = this.priceCats[i].number;
			var pl_bits = Math.pow(2,priceCatNumber-1)+"";
			
			// Seat is available if base_type == 0
			var available = this.createEncoder();
			available.pl_bits = pl_bits;
			available.base_type_low = "0";
			available.base_type_high = "0";
			available.set_run_time_and_mask = "0";
			available.set_run_time_or_mask = this.getStatusValue(priceCatNumber, STATUS_AVAILABLE);
			

			
			//Not available (Sold)
			var not_available_sold = this.createEncoder();
			not_available_sold.pl_bits = pl_bits;
			not_available_sold.set_run_time_or_mask = this.getStatusValue(priceCatNumber, STATUS_NOTAVAILABLE);
			
			//Not available (Held)
//			var not_available_held =  this.createEncoder();
//			not_available_held.pl_bits = pl_bits;
//			not_available_held.seat_flags_and_mask = "4";
//			not_available_held.seat_flags_equal_mask = "4";
//			not_available_held.set_run_time_and_mask = "0";
//			not_available_held.set_run_time_or_mask = this.getStatusValue(priceCatNumber, STATUS_NOTAVAILABLE);
//			
			

			var available_filter = this.createEncoder();
			available_filter.pl_bits = pl_bits;
			available_filter.base_type_low = "0";
			available_filter.base_type_high = "0";
			available_filter.set_run_time_and_mask = "0";
			available_filter.set_run_time_or_mask = this.getStatusValue(priceCatNumber, STATUS_FILTEREDAVAILABLE);

			
			seat_class_encoders.push(available);
			seat_class_encoders.push(not_available_sold);
			available_filter_encoders.push(available_filter);
		}
		
		
		var svl = 
		{
				"seat_class_encoders": seat_class_encoders,
				"not_available_filter_encoders": not_available_filter_encoders,
				"available_filter_encoders": available_filter_encoders
		};
		
		return svl;
	},
	
	getSeatTemplateSelectorHash: function() {
		var modified_match_selectors =[];
		var temp;
		
		temp = 
		{
				run_time_and_mask : "0x000000F",
				run_time_equal_mask : "0x" + STATUS_NOTAVAILABLE,
				template_to_set : "SEAT_NOT_AVAILABLE",
				template_to_overlay :null
		};
		modified_match_selectors.push(temp);
		
		
		temp = 
		{
				run_time_and_mask : "0x000000F",
				run_time_equal_mask : "0x" + STATUS_AVAILABLE,
				template_to_set : "SEAT_AVAILABLE",
				template_to_overlay :null
		};
		modified_match_selectors.push(temp);
		
		
		temp = 
		{
				run_time_and_mask : "0x000000F",
				run_time_equal_mask : "0x" + STATUS_FILTEREDAVAILABLE,
				template_to_set : "SEAT_FILTERED_AVAILABLE",
				template_to_overlay :null
		};
		modified_match_selectors.push(temp);

		
		var svl = 
		{
				modified_match_selectors : modified_match_selectors
		};
		
		return svl;
	},
	
	// Returns a blank encode that does nothing
	// Just set the values you need before using
	createEncoder: function() {
		var encoder =
		{
			pl_bits : "0x7FFFFFFF",
			range_and_mask : "0x7FFFFFFF",
			price_range_low : "0",
			price_range_high : "0",
			base_type_low : "0",
			base_type_high : "0x7FFFFFFF",
			seat_flags_and_mask : "0",
			seat_flags_equal_mask : "0",
			run_time_and_mask : "0",
			run_time_equal_mask : "0",
			qualifier_and_mask : "0", 
			qualifier_equal_mask : "0",
			qualifier_and_mask_2 : "0",
			qualifier_range_low : "0",
			qualifier_range_high : "0x7FFFFFFF",
			set_run_time_and_mask : "0x7FFFFFFF",
			set_run_time_or_mask : "0"
		};
		return encoder;
	},
	
	getStatusValue: function (priceCatNumber, status) {
		return h2d(d2h(priceCatNumber)+status);
	},

	
	// Get the price range for a price category as a formatted string
	// Ex: CAT1: 100EUR - 200EUR
	getPriceCategoryToolTip: function(priceCategoryNumber) {
		var prices = this.eventInfo.prices.price;
		
		var highestPrice = NaN;
		var highestPriceFormatted = '';
		var lowestPrice = NaN;
		var lowestPriceFormatted = '';
		
		var name = priceCategoryNumber;
		
		prices.each(function(price){
			if (price.priceCategory == priceCategoryNumber){
				if (price.price < lowestPrice || isNaN(lowestPrice)) {
					lowestPrice = price.price;
					lowestPriceFormatted = price.priceFormatted;
				}
				if (price.price > highestPrice || isNaN(highestPrice)) {
					highestPrice = price.price;
					highestPriceFormatted = price.priceFormatted;
				}
				for (var i = 0; i<this.priceCatsNum; i++){
					if (this.priceCats[i].number == priceCategoryNumber) {
						name = this.priceCats[i].code;
					}
				}
			}
		}.bind(this));
		
		if (lowestPrice != highestPrice) {
			return name + ': ' + lowestPriceFormatted+' - '+highestPriceFormatted;
		} else {
			return name + ': ' + highestPriceFormatted;
		}
		
	}
	
});





