ISCPriceSlider = Class.create( ISCPriceDisplay, {
tlog: TMDebug.gen_tlog( 'isc-slider' ),
initialize: function( config ) {
this.search_constraints = config.search_constraints;
this.search_constraints.price_slider = this;
this.config = config;
},
setup: function() {
$('price_slider_display').show();
this.increment = this.search_constraints.isc.data.price_slider_incr || 5;
this.value_inputs = this.config.value_inputs;
this.currency_format = this.config.currency || {thou:',', dec:'.', symbol:'$'};
this.currency = new Currency( '333' + this.currency_format.thou + '222' + this.currency_format.dec + '11' );
this.currency_regex = new RegExp('^[1-9][0-9]{0,2}(' + "\\" + this.currency_format.thou + '{0,1}[0-9]{3})*(' + "\\" + this.currency_format.dec + '[0-9]{2})?$');
this.symbol_regex = new RegExp("\\" + this.currency_format.symbol,'g');
this.additional_max_prices = false;
this.handle_index = [];
this.psPopup = new Popup( 'isc-priceslider-info-box', {
close_id: 'pricesliderPopupClose',
zIndex: 105,
links: [{
group: 'edp',
link_id: 'QMark98',
toggle: true,
anchor_align:  { x:  1, y: -1 },
popup_align: { x: -1, y: -1 },
offset: { x: 5, y: 0}
}]
});
this.create_price_data();
this.create_slider_control();
},
reset: function() {
this.slider.reset_handles();
},
register_on_price_change_handler: function( handler ) {
document.observe( 'price_slider:changed', handler );
},
create_slider_control: function() {
this.slider = new Slider( {
slider: this.config.slider,
handle: this.config.handle,
track: this.config.track,
zIndex: 50,
num_handles: 2,
range: this.range,
snap_to: true
} );
document.observe("slider:handle_clicked", this.on_handle_click.bind( this ) );
document.observe("slider:handle_released", this.on_handle_release.bind( this ) );
document.observe( 'slider:change', this.on_slider_change.bind( this ) );
this.eventChange = this.check_user_input.bindAsEventListener(this);
this.fieldFocus = this.accept_user_input.bindAsEventListener(this);
this.keyPress = this.check_keypress.bindAsEventListener(this);
for ( var i = 0 ; i < this.value_inputs.length ; i ++ ) {
this.handle_index[i] = this.range[i];
this.update_input( i, this.range[i] );
var input = this.value_inputs[i];
input.observe("change", this.eventChange);
input.observe("focus", this.fieldFocus);
input.observe("blur", this.fieldFocus);
input.observe("keydown", this.keyPress);
}
},
on_handle_click: function( event ) {
this.start_handle_index = event.memo.handle.index;
this.search_constraints.isc.seat_map.prevent_auto_refresh();
this.slide_active = true;
this.value_inputs[event.memo.index].addClassName('highlight');
click_track.log_datapoint( { price_slider_used: '', __log_only_once__: 'price_slider_used' } );
},
on_handle_release: function( event ) {
this.search_constraints.isc.seat_map.allow_auto_refresh();
this.slide_active = false;
this.value_inputs[event.memo.index].removeClassName('highlight');
if ( event.memo.handle.index != this.start_handle_index ) {
document.fire('price_slider:changed');
}
},
on_slider_change: function( event ) {
this.handle_index[event.memo.index] = event.memo.handle.index;
this.update_input( event.memo.index, event.memo.handle.index );
if ( !this.slide_active ) {
document.fire('price_slider:changed');
}
},
update_input: function(input, index) {
this.value_inputs[input].value = this.indexed_prices[index].formatted;
},
get_price_range: function() {
var min_price = this.indexed_prices[this.handle_index[0]].value;
var max_price = this.indexed_prices[this.handle_index[1]].value;
return [ min_price, max_price ];
},
create_price_data: function() {
var enabled_tts = this.search_constraints.isc.edp.event.get_enabled_ticket_types();
var preferred = this.search_constraints.preferred;
var min_all_in_price;
var max_all_in_price;
var prices = [];
var handle_element = new Element('div', { 'class': this.config.handle } );
handle_element.style.position = 'absolute';
handle_element.style.left = '-1000px';
document.body.appendChild( handle_element );
var max_range = ($(this.config.slider).getWidth() - this.config.track.offset[0] + this.config.track.offset[2] - handle_element.getWidth()) * this.increment;
Element.remove( handle_element );
var i;
for( i = 0 ; i < enabled_tts.length ; i ++ ) {
var tt = enabled_tts[i];
if( !tt.children ) {
for( var price_level in tt.real_price_breakdown ) {
var total_price = tt.real_price_breakdown[price_level].display_charges.total_price;
if( total_price < min_all_in_price || typeof min_all_in_price == 'undefined' ) {
min_all_in_price = total_price;
}
if( total_price > max_all_in_price || typeof max_all_in_price == 'undefined' ) {
max_all_in_price = total_price;
}
if( tt.ext_ticket_type == preferred.ext_ticket_type ) {
prices.push( total_price );
}
}
}
}
prices = prices.sort(function(a,b){return a - b;}).uniq();
this.actual_price = { min:Number( min_all_in_price ), max:Number( max_all_in_price ) };
var disp_max = this.calc_display_max( prices );
var disp_min = this.calc_display_min( min_all_in_price );
if( (disp_max - disp_min) > max_range ) {
var new_cutoff = max_range + disp_min;
disp_max = this.calc_display_max( prices, new_cutoff );
}
if( disp_max == disp_min ) {
disp_max = Math.ceil( prices[ prices.length - 1 ] / this.increment ) * this.increment;
if( disp_max >= this.actual_price.max && this.additional_max_prices ) {
this.additional_max_prices = false;
}
}
this.display_price = { min:disp_min, max:disp_max };
this.range = [ 0, Math.round( (this.display_price.max - this.display_price.min) / this.increment) ];
this.index_range = this.range[1] - this.range[0];
this.display_price_range = disp_max - disp_min;
this.indexed_prices = {};
for ( i = this.range[0] ; i <= this.range[1] ; i ++ ) {
var price = this.display_price.min + i * this.increment;
this.indexed_prices[i] = {
value: price,
formatted: this.currency.format( price )
};
}
if ( this.additional_max_prices ) {
var max_index = this.range[1];
this.indexed_prices[max_index].value = this.actual_price.max;
this.indexed_prices[max_index].formatted += '+';
}
},
check_keypress: function(event) {
if( event.keyCode == Event.KEY_RETURN ) {
this.check_user_input(event);
}
},
accept_user_input: function(event) {
var field = event.element();
if( event.type == 'focus' ) {
this.old_val = field.value;
this.has_focus = field;
field.clear();
field.addClassName('highlight');
}
else {
var value = field.value.strip();
if( value.empty() ) {
field.value = this.old_val;
}
this.has_focus = null;
if( !this.slide_active ) {
field.removeClassName('highlight');
}
}
},
check_user_input: function(event) {
var input = event.element();
var input_index = this.value_inputs[0] == input ? 0 : 1;
var val = input.value;
val = val.strip().replace(this.symbol_regex,'');
var index;
if( val.empty() || !this.valid_currency(val) ) {
index = this.handle_index[input_index];
}
else {
var price = Number( this.scrub_separators( val ) );
index = Math.round( ((price - this.display_price.min) / this.display_price_range) *
this.index_range );
}
if( event.keyCode == Event.KEY_RETURN ) {
input.blur();
}
this.slider.set_handle_index( input_index, index );
this.update_input( input_index, this.handle_index[input_index] );
},
valid_currency: function(val) {
return ( val.match(/^(\d+)$/) || val.match(this.currency_regex) );
},
scrub_separators: function(val) {
if( this.currency_format.dec == ',' ) {
val = val.replace(/\./,'');
val = val.replace(/,/,'.');
}
else {
val = val.replace(/,/,'');
}
return val;
},
calc_display_min: function( val ) {
if( val < this.increment ) {
return 0;
}
else {
return val - ( val % this.increment );
}
},
calc_display_max: function( prices, new_cutoff ) {
var global_median = this.calc_median(prices).toFixed(2);
var q1_list = [];
prices.each( function(price) {
if( price <= global_median ) {
q1_list.push(price);
}
});
var q1 = this.calc_median(q1_list);
var cutoff = new_cutoff ? new_cutoff : ( ( prices[0] * 1 ) + ( 4 * q1 ) );
var display_max = 0;
for( var p = 0 ; p < prices.length ; p++ ) {
var price = Math.ceil( prices[p] );
if( price <= cutoff ) {
display_max = Math.ceil( price / this.increment ) * this.increment;
}
}
if( display_max < this.actual_price.max  ) {
this.additional_max_prices = true;
}
return display_max;
},
calc_median: function( list ) {
var middle = Math.floor(list.length / 2);
if( list.length % 2 != 0 ) {
return list[middle] * 1;
}
else {
return (list[middle - 1] + list[middle]) / 2;
}
}
} );

