SeatSelection = Class.create( {
tlog: TMDebug.gen_tlog( 'classic-seat-sel' ),
initialize: function( event ) {
this.event = event;
},
setup: function() {
this.objects = [];
this.setup_ticket_types();
this.setup_groups();
this.reset();
},
setup_password_prefill: function( tt ) {
var index = tt.password_index;
var val = getQry( 'tm_cat' + index ) ||
new CookieTree( '_E', 'pp' ).get( index );
new CookieTree( '_E', 'pp' ).set( index, val );
tt.password_prefill = val ? val.slice(10) : "";
},
setup_ticket_types: function() {
false;
this.ticket_types = {};
var password_index = 0;
for ( var i = 0 ; i < this.event.ticket_types.length ; i ++ ) {
var tt = this.event.ticket_types[i];
var module_index = i + 1;
var tt_module = new Module( 'classic_ticket_type_' + this.event.event_id + '_' + module_index );
if ( tt.is_enabled && !tt.parent ) {
var select = tt_module.$('quantity_select');
select.options[select.length] = new Option( "__", '' );
var ttobj = {
tt: tt,
module: tt_module,
price_breakdown: {},
quantity_dropdown: new EDPWidget( tt_module.$('quantity_select'), { rows: 10 } ),
price_dropdown: new EDPWidget( tt_module.$('price_select'), {
options: 'price_level_options_' + this.event.event_id + '_' + module_index,
rows: 10
} )
};
select.options.length = select.options.length - 1;
this.objects.push( ttobj );
for ( var price_level in tt.price_breakdown ) {
var price_breakdown = tt.price_breakdown[price_level];
ttobj.price_breakdown[price_breakdown.price_secname] = price_breakdown;
}
if ( tt.password ) {
var offercode = ttobj.module.$('offerCode');
offercode.value = '';
if ( tt.password.scheme_type == 'level_two_mask_rollup' ) {
ttobj.password_index = 'r';
}
else {
ttobj.password_index = password_index;
password_index ++;
}
this.setup_password_prefill( ttobj );
var pw_popup = new Popup( ttobj.module.$('pw_input_popup') );
Event.observe( offercode, 'focus', pw_popup.show.bind( pw_popup, {
anchor_id: offercode,
group: 'pw_input_popup',
anchor_align: {
x: 0,
y: -1
},
popup_align: {
x: 0,
y: 1
},
offset: {
x: 0,
y: -5
}
} ) );
Event.observe( offercode, 'blur', pw_popup.hide.bind( pw_popup ) );
offercode.show();
}
Event.observe( ttobj.quantity_dropdown.dropdown, 'dropdown:change', this.on_quantity_change.bind( this ) );
if ( $H(tt.price_breakdown).keys().length )
Event.observe( ttobj.price_dropdown.dropdown, 'dropdown:change', this.on_price_change.bind( this, ttobj ) );
else
ttobj.price_dropdown.hide();
this.ticket_types[tt.ext_ticket_type] = ttobj;
if ( tt.ticket_info_popup && tt.ticket_info_popup.on_classic ) {
tt_module.$('ticket_type_info_link').show();
tt.ticket_info_popup.addLinks( [ {
group: 'edp',
link_id: tt_module.$('ticket_type_info_link'),
toggle: true,
anchor_align: {
x: 1,
y: -1
},
popup_align: {
x: -1,
y: -1
},
offset: {x:5, y:0},
onShow: function( tt ) {
tt.ticket_info_popup.set_mode( 'classic' );
dcsMultiTrack( 'DCS.dcsuri', "EDP_ticket_type_info", 'WT.ti', "EDP_ticket_type_info" );
}.bind( window, tt )
} ] );
}
}
else {
tt_module.hide();
}
}
},
get_ticket_quantity_descriptions: function() {
var descriptions = [];
for ( var ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
var quantity = this.get_ticket_type_quantity( tt );
if ( quantity > 0 && tt.tt.description ) {
var desc = quantity.toString() + " " + tt.tt.description;
descriptions.push ( desc );
}
}
return descriptions;
},
get_selected_sections: function() {
var sections = [];
for ( var group_id in this.groups ) {
var group = this.groups[group_id];
var select = group.module.$('section_select');
var secname = select.options[select.selectedIndex].value;
if ( this.event.secnames[secname] && this.event.secnames[secname].description )
sections.push( this.event.secnames[secname].description );
}
return sections.length ? sections : [ SeatSelection.best_available ];
},
get_ticket_type_quantity: function( tt ) {
var select = tt.module.$('quantity_select');
return parseInt( select.options[select.selectedIndex].value );
},
get_selected_quantity: function () {
var total = 0;
for ( var ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
var select = tt.module.$('quantity_select');
total = total + this.get_ticket_type_quantity( tt );
}
return total;
},
get_selected_price_levels: function ( tt ) {
var select = tt.module.$('price_select');
var value = select.options[select.selectedIndex].value;
var levels = value.split('|');
return levels;
},
get_selected_price: function ( tt ) {
var price_levels = this.get_selected_price_levels( tt );
if ( price_levels.length ) {
var price_breakdown = tt.tt.price_breakdown[price_levels[0]];
if ( price_breakdown )
return price_breakdown.display_charges.total_price;
}
return 0;
},
on_quantity_change: function() {
false;
if ( this.event.price_limit ) {
false;
var total_purchase = 0;
for ( var ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
total_purchase += this.get_ticket_type_quantity( tt ) * this.get_selected_price( tt );
}
var to_spend = this.event.price_limit - total_purchase;
for ( ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
var max = Math.floor( to_spend / this.get_selected_price( tt ) );
var selected_quantity = this.get_ticket_type_quantity( tt );
var tickets_left = this.event.ticket_limit - selected_quantity;
if ( max > tickets_left )
max = tickets_left;
var ttmax = max + this.get_ticket_type_quantity( tt );
var limits = Object.clone( tt.tt.quantity_limits );
limits.max = ttmax;
this.update_quantity( tt, limits );
}
}
else {
false;
var selected_quantity = this.get_selected_quantity();
var max = this.event.ticket_limit - selected_quantity;
for ( var ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
var ttmax = max + this.get_ticket_type_quantity( tt );
var limits = Object.clone( tt.tt.quantity_limits );
limits.max = ttmax;
this.update_quantity( tt, limits );
}
}
},
on_price_change: function( tt ) {
false;
var price_levels = this.get_selected_price_levels( tt );
tt.price_level_choices = [];
if ( price_levels.length ) {
tt.masks = {
1: 0,
2: 0,
3: 0,
4: 0
};
for ( var i = 0 ; i < price_levels.length ; i ++ ) {
var price_level = price_levels[i];
var price_breakdown = tt.tt.price_breakdown[price_level];
if ( price_breakdown ) {
tt.price_level_choices.push( price_level );
var price_masks = this.event.secnames[price_breakdown.price_secname].masks;
for ( var group_id in price_masks )
tt.masks[group_id] = tt.masks[group_id] | price_masks[group_id];
}
else
tt.masks = {
1: ~0,
2: ~0,
3: ~0,
4: ~0
};
}
}
this.update();
},
on_section_change: function( group_id ) {
false;
var group = this.groups[group_id];
var secname = this.get_selected_section_secname( group );
group.secname_choice = secname;
if ( this.event.secnames[secname] )
group.masks = this.event.secnames[secname].masks;
else
group.masks = {
1: ~0,
2: ~0,
3: ~0,
4: ~0
};
this.update();
},
get_selected_section_secname: function( group ) {
var select = group.module.$('section_select');
return select.options[select.selectedIndex].value;
},
update_quantity: function( tt, quantity ) {
var select = tt.module.$('quantity_select');
quantity = quantity || tt.tt.quantity_limits;
var si = select.selectedIndex;
if ( !si || si < 0 )
si = 0;
select.options.length = 0;
var inc = quantity.inc || 1;
for( var i = 0 ; i <= quantity.max ; i ++ )
if ( !i || i >= quantity.min && !(i % quantity.inc) )
select.options[select.options.length] = new Option( i, i );
select.selectedIndex = si;
tt.quantity_dropdown.update_dropdown();
},
sort_sections: function ( a, b ) {
if ( !this.event.secnames[a] || !this.event.secnames[b] )
return 0;
var a_desc = this.event.secnames[a].description;
var b_desc = this.event.secnames[b].description;
if ( a_desc > b_desc )
return 1;
if ( a_desc < b_desc )
return -1;
return 0;
},
sort_prices: function( tt, a, b ) {
if ( this.mastersearch )
return this.sort_sections( a, b );
else {
if ( !tt.price_breakdown[a] && !tt.price_breakdown[b] )
return 0;
else if ( tt.price_breakdown[a] && !tt.price_breakdown[b] )
return 1;
else if ( !tt.price_breakdown[a] && tt.price_breakdown[b] )
return -1;
var a_price = tt.price_breakdown[a].display_charges.total_price;
var b_price = tt.price_breakdown[b].display_charges.total_price;
if ( a_price < b_price )
return 1;
else if ( a_price > b_price )
return -1;
}
var a_index = parseInt(a.slice(1));
var b_index = parseInt(b.slice(1));
if ( a_index > b_index )
return 1;
else if ( a_index < b_index )
return -1;
return 0;
},
update_prices: function( tt, secnames, mask ) {
false;
var i;
var select = tt.module.$('price_select');
select.options.length = 0;
if ( ! $H(tt.tt.price_breakdown).keys().length )
return;
var options = [];
secnames = secnames.sort( this.sort_prices.bind( this, tt ) );
var last_charges;
for ( i = 0 ; i < secnames.length ; i ++ ) {
var price_secname = secnames[i];
var price_breakdown = tt.price_breakdown[price_secname];
if ( price_breakdown ) {
var price_level = price_breakdown.price_level;
var display_charges = price_breakdown.display_charges;
if ( typeof(last_charges) == 'undefined' ||
last_charges.price != display_charges.price ||
last_charges.sum_fees_and_taxes != display_charges.sum_fees_and_taxes ) {
if ( this.mastersearch )
options.push( new Option( this.event.secnames[price_secname].description, price_level ) );
else
options.push( new Option( display_charges.formatted_total_price, price_level ) );
last_charges = display_charges;
}
else {
var option = options.last();
option.value = option.value + '|' + price_breakdown.price_level;
if ( !tt.price_dropdown.options[option.value] )
tt.price_dropdown.set_option(
option,
tt.price_dropdown.options[price_level].choice
);
}
}
}
if ( !options.length )
options.push( new Option( SeatSelection.not_applicable, 'NA' ) );
else if ( !this.event.suppress_any_price &&
( options.length > 1 ||
options.length > 0 && mask == ~0 ) )
options.unshift( new Option( SeatSelection.any_price, 'AP' ) );
for ( i = 0 ; i < options.length ; i ++ )
select.options[i] = options[i];
this.update_selected_price_index( select, tt.price_level_choices );
tt.price_dropdown.update_dropdown();
},
update_selected_price_index: function( select, price_level_choices ) {
var selected_index = 0;
if ( price_level_choices.length ) {
for ( var i = 0 ; i < select.options.length ; i ++ ) {
var opt_secnames = select.options[i].value.split( '|' );
opt_secnames.each( function( price_level ) {
if ( price_level == price_level_choices[0] )
selected_index = i;
} );
}
}
select.selectedIndex = selected_index;
},
add_ticket_type_form_fields: function( form ) {
for ( var ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
var v = tt.tt.v;
var quantity = this.get_ticket_type_quantity( tt );
form.appendChild( new Element( 'input', { type: 'hidden', name: "w_ext_qty." + v, value: quantity } ) );
if ( quantity ) {
if ( $H(tt.tt.price_breakdown).keys().length ) {
var price_levels = this.get_selected_price_levels( tt );
for ( var i = 0 ; i < price_levels.length ; i ++ ) {
var price_level = price_levels[i];
var secname = '';
if ( tt.tt.price_breakdown[price_level] )
secname = tt.tt.price_breakdown[price_level].price_secname;
if ( this.event.secnames[secname] )
form.appendChild( new Element( 'input', { type: 'hidden', name: "w_vv_ext_price." + v, value: this.event.secnames[secname].v } ) );
else
form.appendChild( new Element( 'input', { type: 'hidden', name: "w_vv_ext_price." + v, value: "" } ) );
}
}
else
form.appendChild( new Element( 'input', { type: 'hidden', name: "w_vv_ext_price." + v, value: "" } ) );
if ( tt.tt.password ) {
form.appendChild( new Element( 'input', { type: 'hidden', name: tt.tt.password.tokens[0].form_name, value: tt.module.$('offerCode').value } ) );
}
}
else
form.appendChild( new Element( 'input', { type: 'hidden', name: "w_vv_ext_price." + v, value: "" } ) );
}
},
validate: function() {
var errors = [];
var total_tickets = this.get_selected_quantity();
if ( total_tickets > this.event.ticket_limit )
errors.push( SeatSelection.error.ticket_limit );
var missing_qty = [];
for ( var ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
if ( tt.tt.password && this.get_ticket_type_quantity( tt ) == 0 && tt.module.$('offerCode').value.replace(/^\s+/,'').replace(/\s+$/,'') )
missing_qty.push ( "\t* " + tt.tt.description );
}
if ( missing_qty.length )
errors.push( SeatSelection.error.select_offer_quantity + ":\n" + missing_qty.join( "\n" ) );
else if ( total_tickets == 0 )
errors.push( SeatSelection.error.select_quantity );
var missing_codes = [];
for ( ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
if ( tt.tt.password && this.get_ticket_type_quantity( tt ) > 0 && !tt.module.$('offerCode').value.replace(/^\s+/,'').replace(/\s+$/,'') )
missing_codes.push ( "\t* " + tt.tt.description );
}
if ( missing_codes.length )
errors.push( SeatSelection.error.enter_code + ":\n" + missing_codes.join( "\n" ) );
if ( errors.length ) {
window.alert( SeatSelection.error.please_fix + "\n\n" + errors.join( "\n" ) );
return false;
}
return true;
},
add_form_values: function( form ) {
this.add_ticket_type_form_fields( form );
this.add_section_form_fields( form );
},
reset: function() {
for ( var ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
tt.price_level_choices = [];
tt.module.$('quantity_select').selectedIndex = 0;
tt.module.$('price_select').selectedIndex = 0;
if ( tt.tt.password )
tt.module.$('offerCode').value = tt.password_prefill;
tt.masks = {
1: ~0,
2: ~0,
3: ~0,
4: ~0
};
}
for ( var group_id in this.groups ) {
var group = this.groups[group_id];
group.secname_choice = "";
group.module.$('section_select').selectedIndex = 0;
group.masks = {
1: ~0,
2: ~0,
3: ~0,
4: ~0
};
}
this.update();
this.on_quantity_change();
},
get_dropdown_mask: function( group, object ) {
var mask = ~0;
for ( var i = 0 ; i < this.objects.length ; i ++ )
if ( this.objects[i] != object )
mask = mask & this.objects[i].masks[group];
return mask;
},
update: function() {
false;
for ( var ext_tt in this.ticket_types ) {
var tt = this.ticket_types[ext_tt];
var mask = this.get_dropdown_mask( 1, tt );
this.update_prices( tt, this.event.get_secname_choices( 1, mask ), mask );
}
for ( var group_id in this.groups ) {
var group = this.groups[group_id];
var mask = this.get_dropdown_mask( group_id, group );
this.update_group( group, this.event.get_secname_choices( group_id, mask ), mask );
}
},
setup_groups: function() {
false;
this.groups = {};
for ( var secname in this.event.secnames ) {
var data = this.event.secnames[secname];
if ( data.masks && data.group >= 2 && data.group <= 4 && !this.groups[data.group] ) {
false;
var group_module = new Module( 'classic_section_' + this.event.event_id + '_' + data.group );
this.groups[data.group] = {
module: group_module,
dropdown: new EDPWidget( group_module.$('section_select'), {
options: 'classic_group_options_' + this.event.event_id + '_' + data.group,
rows: 10,
max_width: 350
} )
};
this.objects.push( this.groups[data.group] );
Event.observe( this.groups[data.group].dropdown.dropdown, 'dropdown:change', this.on_section_change.bind( this, data.group ) );
}
}
},
add_section_form_fields: function( form ) {
for ( var group_id in this.groups ) {
var group = this.groups[group_id];
var select = group.module.$('section_select');
var secname = select.options[select.selectedIndex].value;
var v = "";
if ( this.event.secnames[secname] )
v = this.event.secnames[secname].v;
form.appendChild( new Element( 'input', { type: 'hidden', name: 'w_vv_loc_' + group_id + '.' + this.event.v, value: v } ) );
}
},
update_selected_group_index: function( select, secname_choice ) {
var selected_index = 0;
for ( var i = 0 ; i < select.options.length ; i ++ ) {
var opt_secnames = select.options[i].value.split( '|' );
opt_secnames.each( function( secname ) {
if ( secname == secname_choice )
selected_index = i;
} );
}
select.selectedIndex = selected_index;
},
update_group: function( group, secnames, amsk ) {
false;
var select = group.module.$('section_select');
select.options.length = 0;
if ( secnames.length == 0 )
select.options[0] = new Option( SeatSelection.not_applicable, 'NA' );
else if ( !this.event.suppress_best_available )
select.options[0] = new Option( SeatSelection.best_available, 'BA' );
secnames = secnames.sort( this.sort_sections.bind( this ) );
for ( var i = 0 ; i < secnames.length ; i ++ ) {
var data = this.event.secnames[secnames[i]];
select.options[select.options.length] = new Option( data.description, secnames[i] );
}
this.update_selected_group_index( select, group.secname_choice );
group.dropdown.update_dropdown();
}
} );

