/*
* SABS Agent Search And Booking Software
* <http://www.sabsagent.com>
* Copyright(c) 2001-2008, Micros Travel
*
* @author Jacek Spera <jspera@micros.com>
*/

var MSECS_IN_DAY = 86400000;
var BROCHURE_REQUEST_URL = '/cgi-bin/SAPS/JSONCallHBR.pl';

SABSFactory = {
    // SEARCH FORMS
    IsFromOld: false,
    getAirports: function(where){
        return [
            ['*LON', 'London Airports (LON)'],
            ['*GBR', 'Great Britain (GBR)'],
            ['*ANG', 'Anglian Airports (ANG)'],
            ['*NWA', 'North West Airports (NWA)'],
            ['*NEA', 'North East Airports (NEA)'],
            ['*MID', 'Midland Airports (MID)'],
            ['*SWA', 'South West & Wales (SWA)'],
            ['*GBS', 'Scottish Airports (GBS)'],
            ['*IRL', 'Irish Airports (IRL)'],
            ['*GIN', 'Northern Ireland (GIN)'],
            ['*GIR', 'Republic of Ireland (GIR)'],
            ['ABZ', 'Aberdeen (ABZ)'],
            ['BHD', 'Belfast City (BHD)'],
            ['BFS', 'Belfast International (BFS)'],
            ['BHX', 'Birmingham (BHX)'],
            ['BLK', 'Blackpool (BLK)'],
            ['BOH', 'Bournemouth (BOH)'],
            ['BRS', 'Bristol (BRS)'],
            ['CWL', 'Cardiff (CWL)'],
            ['DSA', 'Doncaster (DSA)'],
            ['EMA', 'East Midlands (EMA)'],
            ['EDI', 'Edinburgh (EDI)'],
            ['EXT', 'Exeter (EXT)'],
            ['GLA', 'Glasgow (GLA)'],
            ['GCI', 'Guernsey (GCI)'],
            ['HUY', 'Humberside (HUY)'],
	    ['IOM', 'Isle of Man (IOM)'],
            ['INV', 'Inverness (INV)'],
            ['JER', 'Jersey (JER)'],
            ['NOC', 'Knock (NOC)'],
            ['LBA', 'Leeds Bradford (LBA)'],
            ['LCY', 'London City (LCY)'],
            ['LGW', 'Gatwick (LGW)'],
            ['LHR', 'Heathrow (LHR)'],
            ['LTN', 'Luton (LTN)'],
            ['STN', 'Stansted (STN)'],
            ['LPL', 'Liverpool (LPL)'],
            ['MAN', 'Manchester (MAN)'],
            ['NCL', 'Newcastle (NCL)'],
            ['NWI', 'Norwich (NWI)'],
            ['SOU', 'Southampton (SOU)'],
            ['MME', 'Teeside (MME)'],
            ['ORK', 'Cork (ORK)'],
            ['DUB', 'Dublin (DUB)'],
            ['KIR', 'Kerry (KIR)'],
	    ['NOC', 'Knock (NOC)'],	
            ['SNN', 'Shannon (SNN)']
        ];
    },
    getCombo: function(type, comboCfg, searchType){
        comboCfg = comboCfg || {};
        var cfg = {
            typeAhead: true,
			cls:'micros-combobox',
            mode: 'local',
            minChars: 3,
            selectOnFocus: true,
            allowBlank: false,
            forceSelection: true,
            anchor: '-10'
        };
        switch(type){
            case 'departure':
/* Defined in ../Components/form/DepartureComboBox.js */            
               return new DepartureComboBox(Ext.applyIf({
                    xtype: 'departurecombo',
                    // custom classes >
                    cls: 'micros-formelem micros-combobox micros-departure-combobox',                    ctCls: 'micros-formelem-ct micros-combobox-ct micros-departure-combobox-ct',
                    itemCls: 'micros-formelem-item micros-combobox-item micros-departure-combobox-item',
                    // < custom classes
                    fieldLabel: comboCfg.fieldLabel || 'Departure',
                    hiddenName:'startPoint',
                    name: 'startPoint',
                    width:10,
		    id: 'depCombo',
                    store: new Ext.data.SimpleStore({
                        fields: ['iata', 'airport'],
                        data : SABSFactory.getAirports(),
                        sortInfo: {field: 'airport', direction: 'ASC'}
                    }),
                    displayField:'airport',
                    valueField:'iata',
                    triggerAction: 'all'
                }, cfg));
            
            case 'destination':
               return new Ext.form.ComboBox(Ext.applyIf({
                    xtype: 'combo',
                    // custom classes >
                    cls: 'micros-formelem micros-combobox micros-destination-combobox',
                    ctCls: 'micros-formelem-ct micros-combobox-ct micros-destination-combobox-ct',
                    itemCls: 'micros-formelem-item micros-combobox-item micros-destination-combobox-item',
                    // < custom classes
                    fieldLabel: comboCfg.fieldLabel || 'Destination',
                    hiddenName:'endPoint',
                    emptyText: 'Please type your destination',
                    hideTrigger: true,
	            queryParam:'search', 
		    id: 'destCombo',			
                    mode: 'remote',
                    minChars: 3,
                    store: new Ext.data.JsonStore({
                        url: "/Search/search.php",
                        root: 'results',
                        id: 'code',
                        fields: [ 'code', {name: 'destination', type: 'string'},
                            {name: 'rank', type: 'float'}, 'gateway' ],
                        sortInfo: {field: 'destination', direction: 'ASC'}
                    }),
                    displayField:'destination',
                    listeners: {
                        // Fill in the gateway and resortcode hidden fields
                        // when a destination is selected.
                        'select': function(cmp, rec, index){
                            var gateway = Ext.getCmp('gateway');
                            if ( gateway ) {
                                gateway.setValue(rec.get('gateway') );
                            }
                            var resortcode = Ext.getCmp('resortcode');
                            if ( resortcode ) {
                                resortcode.setValue( rec.get('code') );
                            }
                        }
                    }
                }, cfg));
			case 'destGroup':		
				return new Ext.form.ComboBox({
					cls: 'micros-formelem micros-combobox micros-boardbasis-combobox',
					ctCls: 'micros-formelem-ct micros-combobox-ct micros-boardbasis-combobox-ct',
					itemCls: 'micros-formelem-item micros-combobox-item micros-boardbasis-combobox-item',
					xtype:'combo',
					id:'destCombo',
					fieldLabel:'Going To',
					name:'DestinationGroupCode',
					hiddenName:'endPoint',
					valueField:'code',
					triggerAction:'all',
					typeAhead: false,
					forceSelection:true,
					 // make the drop down list resizable
					resizable:true,
					editable:false,
					minListWidth:260,
					allowBlank:false,
					anchor:'-10',
				   // store getting items from server
				         store:new Ext.data.JsonStore({
					   id: 'groupingCode',
					   root:'Destinations',
					   //,totalProperty:'totalCount'
					   fields:[
						   {name:'name', type:'string'}
						   ,{name:'type', type:'string'}
						   ,{name:'code', type:'string'}
						 ],
					   sortInfo: {field: 'name', direction: 'ASC'},
					   url:'/cgi-bin/jsonDests.pl'
					 }),
				   tpl:'<tpl for="."><div class="x-combo-list-item">{name} ({code})</div></tpl>',
				   listeners:{
				   select:function(combo, record, index) {
				        this.setRawValue(record.get('name') + ' (' + record.get('code')+')');
                       			var type = Ext.getCmp('type'); 
                       			if (type) {                  
                       			   type.setValue(record.get('type'));
                       			}
				   },     
				   blur:function() {
				       var val = this.getRawValue();
				       this.setRawValue.defer(1, this, [val]);
				   }
				  }
			});		
            case 'boardbasis':
                return new Ext.form.ComboBox({
                    xtype: 'combo',
                    // custom classes >
                    cls: 'micros-formelem micros-combobox micros-boardbasis-combobox',
                    ctCls: 'micros-formelem-ct micros-combobox-ct micros-boardbasis-combobox-ct',
                    itemCls: 'micros-formelem-item micros-combobox-item micros-boardbasis-combobox-item',
                    // < custom classes
                    fieldLabel: 'Board Basis',
                    hiddenName:'BoardBasis',
                    store: new Ext.data.SimpleStore({
                        fields: ['values','description'],
                            data : [
                                ['', 'All'],
                                ['SC', 'Self Catering'],
                                ['BB', 'Bed and Breakfast'],
                                ['HB', 'Half Board'],
                                ['FB', 'Full Board'],
                                ['AI', 'All Inclusive']
                            ]
                    }),
                    displayField:'description',
                    valueField:'values',
                    hideTrigger: false,
                    mode: 'local',
                    allowBlank: true,
                    editable: false,
                    anchor: '-10',
                    triggerAction: 'all'
                });
			case 'price':
				return new Ext.form.ComboBox({
                        fieldLabel: 'Price Range',
                        hiddenName:'price',
                        store: new Ext.data.SimpleStore({
                            fields: ['desc','price'],
                            data: [
                                ['Display All',''],['Up to &pound;100',''],['&pound;100 - &pound;200',''],['&pound;200 - &pound; 300',''],['&pound;300 - &pound;400',''],['Up to &pound;200',''],['Up to &pound;200',''],['Up to &pound;300',''],['Up to &pound;400',''],['Up to &pound;500','']
                            ]
                        }),
                        displayField:'desc',
                        valueField:'price',
                        typeAhead: true,
                        mode: 'local',
                        triggerAction: 'all',
                        emptyText:'Price',
                        selectOnFocus:true,
                        width:100
                    });
			case 'sideDate':		
				return new Ext.form.ComboBox({
                        fieldLabel: 'Days either side',
                        hiddenName:'days',
                        store: new Ext.data.SimpleStore({
                            fields: ['desc','days'],
                            data: [
                                ['Exact Date Only',0],['1 Day',1],['3 Days',3],['5 Days',5],['7 Days',7],['9 Days',9]
                            ]
                        }),
                        displayField:'desc',
                        valueField:'days',
                        typeAhead: true,
                        mode: 'local',
                        triggerAction: 'all',
                        selectOnFocus:true,
                        width:120
                    });	
			case 'numResults':
				return new Ext.form.ComboBox({
                        fieldLabel: 'Results per page',
                        hiddenName:'noResult',
                        store: new Ext.data.SimpleStore({
                            fields: ['results'],
                            data: [
                                [10],[20],[30],[40],[50]
                            ]
                        }),
                        displayField:'results',
                        valueField:'results',
                        typeAhead: true,
                        mode: 'local',
                        triggerAction: 'all',
                        selectOnFocus:true,
                        width:50
                    });
			case 'numNights':		
				return new Ext.form.ComboBox({
                        fieldLabel: 'Number of Nights',
                        hiddenName:'nights',
                        store: new Ext.data.SimpleStore({
                            fields: ['desc','nights'],
                            data: [
                                ['One Way',''],['Up to 4 Nights',''],['5 to 10 Nights',''],['11 to 17 Nights',''],['18+ Nights',''],['1 Night',1],['2 Night',2],['3 Nights',3],['4 Nights',4],['5 Nights',5],['6 Nights',6],['7 Nights',7],['8 Nights',8],['9 Nights',9],['10 Nights',10],['11 Nights',11],['12 Nights',12]
                            ]
                        }),
                        displayField:'desc',
                        valueField:'nights',
                        typeAhead: true,
                        mode: 'local',
                        triggerAction: 'all',
                        emptyText:'Number of Nights',
                        selectOnFocus:true,
                        width:130
                    });					
            case 'rating':
                return new Ext.form.ComboBox({
                    xtype: 'combo',
                    // custom classes >
                    cls: 'micros-formelem micros-combobox micros-rating-combobox',
                    ctCls: 'micros-formelem-ct micros-combobox-ct micros-rating-combobox-ct',
                    itemCls: 'micros-formelem-item micros-combobox-item micros-rating-combobox-item',
                    // < custom classes
                    fieldLabel: 'Rating',
                    hiddenName:'Rating',
                    store: new Ext.data.SimpleStore({
                        fields: ['values','description'],
                        data : [
                            ['', 'All'],
                            ['2,3,4,5', '2-5'],
                            ['3,4,5', '3-5'],
                            ['4,5', '4-5'],
                            ['5,5', '5']
                        ]
                    }),
                    displayField:'description',
                    valueField:'values',
                    hideTrigger: false,
                    mode: 'local',
                    allowBlank: true,
                    editable: false,
                    anchor: '-10',
                    triggerAction: 'all'
                });
        }
    },
    getTravellersGroup: function(mini){
        var cfg = {
            xtype: 'numberfield',
            // custom classes >
            cls: 'micros-formelem micros-numberfield micros-travellers-numberfield',
            ctCls: 'micros-formelem-ct micros-numberfield-ct micros-travellers-numberfield-ct',
            itemCls: 'micros-formelem-item micros-numberfield-item micros-travellers-numberfield-item',
            // < custom classes
            allowBlank: true,
            allowDecimals: false,
            allowNegative: false,
            maxValue: 8,
            anchor: '-10'
        };
        var adultsf = new Ext.form.NumberField(
            Ext.applyIf({
                fieldLabel: 'adults',
                allowBlank:false,
                name: 'Adults',
                value: 1,
                minValue: 1,
                maxValue: 9
            }, cfg)
        );
        var childsf = new Ext.form.NumberField(
            Ext.applyIf({
                fieldLabel: 'children',
                name: 'Children'
            }, cfg)
        );
        var infantsf = new Ext.form.NumberField(
            Ext.applyIf({
                fieldLabel: 'infants',
                name: 'Infants',
                anchor: '0'
            }, cfg)
        );

        return {
            xtype: 'fieldset',
            // custom classes >
            cls: 'micros-formelem micros-fieldset micros-travellers-fieldset',
            ctCls: 'micros-formelem-ct micros-fieldset-ct micros-travellers-fieldset-ct',
            itemCls: 'micros-formelem-item micros-fieldset-item micros-travellers-fieldset-item',
            // < custom classes
            layout: 'form',
            autoHeight: true,
            title: 'Number of Travellers',
            labelSeparator: ':',
            anchor: '-10',
            style: 'margin-top: 15px;',
            items: [{
                layout: 'form',
                border:false,
                items: [{
                    layout: 'column',
                    border:false,
                    defaults: {
                        columnWidth: 0.33,
                        layout: 'form',
                        anchor: '0',
                        border:false
                    },
                    items: [
                        {items: adultsf},
                        {items: childsf},
                        {items: infantsf}
                    ]
                }]
            }]
        };
    },
    getFormButtons: function(){
        return [{
            text: 'Clear form',
            handler: function(b){
                b.ownerCt.getForm().reset();
            }
        },{
            text: 'Search'
            //handler: function(b){
                //b.ownerCt.submit();
            //}
        }];
    },
    getDateGroup: function(cfg){
        var day = new Date().clearTime().add(Date.DAY, 1); 
        var dateFieldDefaults = {
            allowBlank:false,
            format: 'd/m/y',
            minValue: day,
            showToday: false,
            anchor: '-10',
            xtype: 'datefield'
        /*   onTriggerClick : function(){
                if(this.disabled){
                    return;
                }
                if(!this.menu){
                    this.menu = new Ext.menu.DateMenu();
                }
                Ext.apply(this.menu.picker,  {
                    minDate : this.minValue,
                //    maxDate : this.maxValue,
                  //  disabledDatesRE : this.ddMatch,
                 //   disabledDatesText : this.disabledDatesText,
                 //   disabledDays : this.disabledDays,
                //    disabledDaysText : this.disabledDaysText,
                  //  format : this.format,
                   // showToday : this.showToday,
                   // minText : String.format(this.minText, this.formatDate(this.minValue)),
                   // maxText : String.format(this.maxText, this.formatDate(this.maxValue))
                });
                this.menu.on(Ext.apply({}, this.menuListeners, {
                    scope:this
                }));
                this.menu.picker.setValue(this.minValue);
                this.menu.show(this.el, "tl-bl?");
            }*/
        };
    var items;
	if(cfg.endDateLabel && cfg.startDateLabel){
          items = [{
            items:[Ext.applyIf({
                // custom classes >
                cls: 'micros-formelem micros-datefield micros-startdate-datefield',
                ctCls: 'micros-formelem-ct micros-datefield-ct micros-startdate-datefield-ct',
                itemCls: 'micros-formelem-item micros-datefield-item micros-startdate-datefield-item',
                // < custom classes
                fieldLabel: cfg.startDateLabel,
                name: 'startDate',
                id: 'startDate'+ cfg.suffix,
                value: day,
                endDateField: 'endDate' + cfg.suffix,
                vtype: 'daterange',
                maxValue: null,
                listeners: {
	    valid: function(datefield){
	               var inbound  = Ext.getCmp( 'endDate' + cfg.suffix );
                       if (inbound){
	               	   inbound.minValue = datefield.getValue();
	               	   datefield.setMaxValue( null );
        	           if ( inbound.getValue() < datefield.getValue() || inbound.getValue() >  datefield.getValue().add(Date.MONTH, 1) ) {  
        	               inbound.setValue( inbound.minValue.add(Date.DAY, 7) );
        	               inbound.setMaxValue( inbound.minValue.add(Date.MONTH, 1) );
        	               inbound.clearInvalid();
        	           }
        	           else {
        	               inbound.clearInvalid();
        	           }
		       }
	           }
    }
                
                
            }, dateFieldDefaults),Ext.applyIf({
                // custom classes >
                cls: 'micros-formelem micros-datefield micros-enddate-datefield',
                ctCls: 'micros-formelem-ct micros-datefield-ct micros-enddate-datefield-ct',
                itemCls: 'micros-formelem-item micros-datefield-item micros-enddate-datefield-item',
                // < custom classes
                fieldLabel: cfg.endDateLabel,
                name: 'endDate',
                maxValue: null,
                id: 'endDate' + cfg.suffix,
                startDateField: 'startDate' + cfg.suffix,
                vtype: 'daterange'
            }, dateFieldDefaults)]
          }];
	}
    else if(cfg.endDateLabel){
       items = [{
           items:[Ext.applyIf({
               // custom classes >
              cls: 'micros-formelem micros-datefield micros-enddate-datefield',
               ctCls: 'micros-formelem-ct micros-datefield-ct micros-enddate-datefield-ct',
               itemCls: 'micros-formelem-item micros-datefield-item micros-enddate-datefield-item',
               // < custom classes
              		fieldLabel: cfg.endDateLabel,
	   	name: 'endDate',
	   	id: 'endDate'+ cfg.suffix
           }, dateFieldDefaults)]
       }];
    }
    else if(cfg.startDateLabel){
	    items = [{
		    items:[Ext.applyIf({
			// custom classes >
			cls: 'micros-formelem micros-datefield micros-startdate-datefield',
			ctCls: 'micros-formelem-ct micros-datefield-ct micros-startdate-datefield-ct',
			itemCls: 'micros-formelem-item micros-datefield-item micros-startdate-datefield-item',
			// < custom classes
			fieldLabel: cfg.startDateLabel,
			name: 'startDate',
			id: 'startDate'+ cfg.suffix,
			value: day,
			   listeners: {
	    valid: function(datefield){
	               var inbound  = Ext.getCmp( 'endDate' + cfg.suffix );
                       if (inbound){
	               	   inbound.minValue = datefield.getValue();
	               	   datefield.setMaxValue( null );
        	           if ( inbound.getValue() < datefield.getValue() || inbound.getValue() >  datefield.getValue().add(Date.MONTH, 1) ) {  
        	               inbound.setValue( inbound.minValue.add(Date.DAY, 7) );
        	               inbound.setMaxValue( inbound.minValue.add(Date.MONTH, 1) );
        	               inbound.clearInvalid();
        	           }
        	           else {
        	               inbound.clearInvalid();
        	           }
		       }
	           }
    }
		    }, dateFieldDefaults)]
		}];
	}
        if(cfg.time){
         if(cfg.endDateLabel && cfg.startDateLabel ){
		items = items.concat({
                defaults: {
                    allowBlank:false,
                    format: 'H:i',
                    increment: 15,
                    anchor: '-10'
                },
                defaultType: 'timefield',
                items:[{
                    // custom classes >
                    cls: 'micros-formelem micros-timefield micros-startdate-timefield',
                    ctCls: 'micros-formelem-ct micros-timefield-ct micros-startdate-timefield-ct',
                    itemCls: 'micros-formelem-item micros-timefield-item micros-startdate-timefield-item',
                    // < custom classes
                    fieldLabel: cfg.startTimeLabel || 'Time',
                    name: 'startTime',
                    id: 'startTime'+ cfg.suffix,
                    value: '12:00'
                },{
                    // custom classes >
                    cls: 'micros-formelem micros-timefield micros-enddate-timefield',
                    ctCls: 'micros-formelem-ct micros-timefield-ct micros-enddate-timefield-ct',
                    itemCls: 'micros-formelem-item micros-timefield-item micros-enddate-timefield-item',
                    // < custom classes
                    fieldLabel: cfg.endTimeLabel || 'Time',
                    name: 'endTime',
                    id: 'endTime' + cfg.suffix,
                    value: '12:00'
                }]
            });
	} 
	else if(cfg.endDateLabel){
            items = items.concat({
                defaults: {
                    allowBlank:false,
                    format: 'H:i',
                    increment: 15,
                    anchor: '-10'
                },
                defaultType: 'timefield',
                items:[{
                    // custom classes >
                    cls: 'micros-formelem micros-timefield micros-enddate-timefield',
                    ctCls: 'micros-formelem-ct micros-timefield-ct micros-enddate-timefield-ct',
                    itemCls: 'micros-formelem-item micros-timefield-item micros-enddate-timefield-item',
                    // < custom classes
                    fieldLabel: cfg.endTimeLabel || 'Time',
                    name: 'endTime',
                    id: 'endTime'+ cfg.suffix,
                    value: '12:00'
                }]
            });
	  }
 	 else if(cfg.startDateLabel){
	    items = items.concat({
                defaults: {
                    allowBlank:false,
                    format: 'H:i',
                    increment: 15,
                    anchor: '-10'
                },
                defaultType: 'timefield',
                items:[{
                    // custom classes >
                    cls: 'micros-formelem micros-timefield micros-startdate-timefield',
                    ctCls: 'micros-formelem-ct micros-timefield-ct micros-startdate-timefield-ct',
                    itemCls: 'micros-formelem-item micros-timefield-item micros-startdate-timefield-item',
                    // < custom classes
                    fieldLabel: cfg.startTimeLabel || 'Time',
                    name: 'startTime',
                    id: 'startTime'+ cfg.suffix,
                    value: '12:00'
                }]
            });
	 }
        }
        else if(cfg.columns == 2){
            items = [{
                items: items[0].items[0]
            },{
                items: items[0].items[1]
            }];
        }
        return {
            border: false,
            items: [{
                layout: cfg.rows===1 ? 'form' : 'column',
                id: 'dategroup' + cfg.suffix,
                border:false,
                defaults: {
                    columnWidth:0.5,
                    layout: 'form',
                    labelAlign: 'top',
                    border:false
                },
                items: items
            }]
        };
 },
    getAccomSingleRoomGroup: function(num){
        return {
            layout: 'column',
            hidden: num > 0 ? true : false,
            labelAlign: 'left',
            labelWidth: 50,
            border: false,
            defaults: {
                layout: 'form',
                anchor: '0',
                labelAlign: 'left',
                border:false
            },
            items: [{
                columnWidth: 0.5,
                items: new Ext.form.Label({
                    text: 'Room ' + (num+1),
                    // custom classes >
                    cls: 'x-form-item micros-formelem micros-label micros-roomnumber-label',
                    ctCls: 'micros-formelem-ct micros-label-ct micros-roomnumber-label-ct',
                    itemCls: 'micros-formelem-item micros-label-item micros-roomnumber-label-item'
                    // < custom classes
                })
            },{
                columnWidth: 0.25,
                items: {
                    // custom classes >
                    cls: 'micros-formelem micros-numberfield micros-roomoccupants-numberfield',
                    ctCls: 'micros-formelem-ct micros-numberfield-ct micros-roomoccupants-numberfield-ct',
                    itemCls: 'micros-formelem-item micros-numberfield-item micros-roomoccupants-numberfield-item',
                    // < custom classes
                    xtype: 'numberfield',
                    hideLabel: true,
                    fieldLabel: 'Adults',
                    name: 'room_occupancy',
                    maxValue: 9,
                    allowDecimals: false,
                    disabled: num > 0 ? true : false,
                    anchor: '-10',
                    minValue: 1,
                    value: 1,
                    allowBlank: false
                }
            },{
                columnWidth: 0.25,
                items: {
                    xtype: 'numberfield',
                    // custom classes >
                    cls: 'micros-formelem micros-numberfield micros-roomoccupants-numberfield',
                    ctCls: 'micros-formelem-ct micros-numberfield-ct micros-roomoccupants-numberfield-ct',
                    itemCls: 'micros-formelem-item micros-numberfield-item micros-roomoccupants-numberfield-item',
                    // < custom classes
                    fieldLabel: 'Children',
                    name: 'room_occupancy',
                    hideLabel: true,
                    maxValue: 9,
                    minValue: 0,
                    allowDecimals: false,
                    disabled: num > 0 ? true : false,
                    anchor: '-10'
                }
            }]
        };
    },
    getAccommRoomGroup: function(){
        return {
            border:false,
            items: [{
                layout: 'column',
                labelAlign: 'left',
                labelWidth: 50,
                border: false,
                defaults: {
                    layout: 'form',
                    anchor: '0',
                    labelAlign: 'left',
                    border:false
                },
                items: [{
                    columnWidth: 0.25,
                    items: new Ext.form.Label({
                        text: 'No. of Rooms',
                        height: 22,
                        // custom classes >
                        cls: 'x-form-item micros-formelem micros-label micros-roomcount-label',
                        ctCls: 'micros-formelem-ct micros-label-ct micros-roomcount-label-ct',
                        itemCls: 'micros-formelem-item micros-label-item micros-roomcount-label-item'
                        // < custom classes
                        })
                },{
                    columnWidth: 0.25,
                    items: {
                        xtype: 'combo',
                        // custom classes >
                        cls: 'micros-formelem micros-combobox micros-rating-combobox',
                        ctCls: 'micros-formelem-ct micros-combobox-ct micros-rating-combobox-ct',
                        itemCls: 'micros-formelem-item micros-combobox-item micros-rating-combobox-item',
                        // < custom classes
                        hideLabel: true,
                        hideTrigger: true,
                        hiddenName:'Rating',
                        store: new Ext.data.SimpleStore({
                            fields: ['v'],
                            data: [
                                [1], [2], [3], [4], [5], [6], [7], [8], [9]
                            ]
                        }),
                        displayField:'v',
                        valueField:'v',
                        value: 1,
                        mode: 'local',
                        allowBlank: false,
                        editable: false,
                        triggerAction: 'all',
                        anchor: '-10',
                        listeners: {
                            select: function(b, r, i){
                                var rnum = r.data.v;
                                var ct = b.ownerCt.ownerCt.ownerCt;
                                var rows = ct.items.getRange(1);
                                Ext.each(rows, function(o,i,a){
                                    var on = i < rnum;
                                    o.setVisible(on);
                                    o.items.get(1).items.get(0).setDisabled(!on);
                                    o.items.get(2).items.get(0).setDisabled(!on);
                                });
                                ct.doLayout();
                            }
                        }
                    }
                },{
                    columnWidth: 0.25,
                    items: new Ext.form.Label({
                        // custom classes >
                        cls: 'micros-formelem micros-label micros-roomoccupants-label',
                        ctCls: 'micros-formelem-ct micros-label-ct micros-roomoccupants-label-ct',
                        itemCls: 'micros-formelem-item micros-label-item micros-roomoccupants-label-item',
                        // < custom classes
                        text: 'Adults',
                        name: 'Adults',
                        style: 'margin-top:30px',
                        cls: 'x-form-item'
                    })
                },{
                    columnWidth: 0.25,
                    items: new Ext.form.Label({
                        text: 'Children',
                        style: 'margin-top:30px',
                        cls: 'x-form-item'
                    })
                }]
            },
                SABSFactory.getAccomSingleRoomGroup(0),
                SABSFactory.getAccomSingleRoomGroup(1),
                SABSFactory.getAccomSingleRoomGroup(2),
                SABSFactory.getAccomSingleRoomGroup(3),
                SABSFactory.getAccomSingleRoomGroup(4),
                SABSFactory.getAccomSingleRoomGroup(5),
                SABSFactory.getAccomSingleRoomGroup(6),
                SABSFactory.getAccomSingleRoomGroup(7),
                SABSFactory.getAccomSingleRoomGroup(8)
            ]
        };
    },
    getFlexibleDatesCheckbox: function(){
        return {
            xtype: 'checkbox',
            // custom classes >
            cls: 'micros-formelem micros-checkbox micros-datesflexible-checkbox',
            ctCls: 'micros-formelem-ct micros-checkbox-ct micros-datesflexible-checkbox-ct',
            itemCls: 'micros-formelem-item micros-checkbox-item micros-datesflexible-checkbox-item',
            // < custom classes
            name: 'datesFlexible',
            hideLabel: true,
            boxLabel: 'My dates are flexible +/-3 days',
            checked: true
        };
    },
    getForm: function(type, ctWidth){
        var cfg = {
            header: false,
            labelAlign: 'left',
            buttonAlign: 'right',
            labelSeparator: '',
            floating: false,
            closable: false,
            border: false,
            defaults: {
                border: false
            },
            layout: 'form',
            autoHeight:true,
            buttons: SABSFactory.getFormButtons()
    };
    var colCfg = {
        layout:'column',
        style: {
            borderBottom: '1px solid #99BBE8',
            marginRight: '10px'
        },
        border:false,
        defaults: {
            columnWidth:0.5,
            layout: 'form',
            labelAlign: 'top',
            border:false
        }
    };

    // For flight forms: Enable/disable the return date field based on the
    // flight type
    var flightTypeChange = function(f, checked) {
        var enable = ( f.inputValue === 'R' && checked );
        var returnDate = Ext.getCmp('endDate-flight');
        returnDate.setDisabled(!enable);
        returnDate.validate();
    };

    if(ctWidth && ctWidth < 300){
    /*
        if(type=='flight'){
            return new Ext.form.FormPanel(Ext.applyIf({
				items: [
					SABSFactory.getDateGroup({
                          startDateLabel: 'Departure Date',
							//rows: 1,
                          suffix: '-flight'                                 
                          }),
					new Ext.form.DateField({
                        fieldLabel: 'Departure Date',
                        name: 'dob',
                        width:190,
                        allowBlank:false
                    }),
					SABSFactory.getCombo('sideDate'),
					SABSFactory.getCombo('numNights'),
					SABSFactory.getCombo('price'),
					SABSFactory.getCombo('departure',{fieldLabel: 'Leaving From'}),
					SABSFactory.getCombo('destGroup'),
					SABSFactory.getTravellersGroup(),
					SABSFactory.getCombo('numResults')
                ]
			
			}, cfg));
		}
	*/	
		if(type=='flight'){
            return new Ext.form.FormPanel(Ext.applyIf({
                items: [{
                    layout: 'form',
                    style: {
                        borderBottom: '1px solid #99BBE8',
                        marginBottom: '10px',
                        marginRight: '10px'
                    },
                    items:[{
                        xtype: 'radiogroup',
                        // custom classes >
                        cls: 'micros-formelem micros-radiogroup micros-flighttype-radiogroup',
                        ctCls: 'micros-formelem-ct micros-radiogroup-ct micros-flighttype-radiogroup-ct',
                        itemCls: 'micros-formelem-item micros-radiogroup-item micros-flighttype-radiogroup-item',
                        // < custom classes
                        fieldLabel: 'Flight type',
                        id: 'flightType',
                        //anchor: Ext.isIE6 ? '100%':'0',
                        //width: 250,
                        columns:1,
                        //autoHeight:true,
                        items: [{
                                boxLabel: 'One&nbsp;way',
                                name: 'FlightType',
                                inputValue: 'O',
                                listeners: {
                                    check: flightTypeChange
                                }
                            },{
                                boxLabel: 'Return',
                                name: 'FlightType',
                                inputValue: 'R',
                                checked: true,
                                listeners: {
                                    check: flightTypeChange
                                }
                            }]
                        }]
                    },{
                        border:false,
                        defaults: {
                            layout: 'form',
                            labelAlign: 'top',
                            border:false
                        },
                        items: [{
                            items: [
                                SABSFactory.getCombo('departure',
                                    {fieldLabel: 'Leaving From'}),
					            SABSFactory.getCombo('destGroup'),
                                {
                                    xtype: 'hidden',
                                    id: 'type'
                                },
                              /*  SABSFactory.getCombo('destGroup',
                                    {fieldLabel: 'Going To'}),
                                {
                                    xtype: 'hidden',
                                    id: 'gateway'
                                },*/
                                SABSFactory.getDateGroup({
                                    startDateLabel: 'Departure Date',
                                    endDateLabel: 'Return Date',
                                    suffix: '-flight',
                                    columns: 2
                                }),
                                SABSFactory.getFlexibleDatesCheckbox(),
                            {
                                xtype: 'checkbox',
                                // custom classes >
                                cls: 'micros-formelem micros-checkbox micros-directflights-checkbox',
                                ctCls: 'micros-formelem-ct micros-checkbox-ct micros-directflights-checkbox-ct',
                                itemCls: 'micros-formelem-item micros-checkbox-item micros-directflights-checkbox-item',
                                // < custom classes
                                hideLabel: true,
                                id: 'DirectFlights',
                                boxLabel: 'Direct Flights Only'
                            },
                                // TODO: make sure this needs
                                // to be instantiated here
                                new Ext.form.ComboBox({
                                    xtype: 'combo',
                                    // custom classes >
                                    cls: 'micros-formelem micros-combobox micros-seatclass-combobox',
                                    ctCls: 'micros-formelem-ct micros-combobox-ct micros-seatclass-combobox-ct',
                                    itemCls: 'micros-formelem-item micros-combobox-item micros-seatclass-combobox-item',
                                    // < custom classes
                                    fieldLabel: 'Seat class',
                                    hiddenName:'seatClass',
                                    store: new Ext.data.SimpleStore({
                                        fields: ['values','description'],
                                        data: [
                                            ['', 'Any'],
                                            ['E', 'Economy'],
                                            ['B', 'Business'],
                                            ['F', 'First']
                                        ]
                                    }),
                                    displayField:'description',
                                    valueField:'values',
                                    hideTrigger: false,
                                    mode: 'local',
                                    allowBlank: true,
                                    editable: false,
                                    anchor: '-10',
                                    triggerAction: 'all'
                                }),
                                SABSFactory.getTravellersGroup(true)
                            ]
                        }]
                    }]
                }, cfg));
            }
			
			else if(type=='carhire') {
                return new Ext.form.FormPanel(Ext.applyIf({   
                    items: [{
                        layout: 'form',
                        border:false,
                        defaults: {
                            layout: 'form',
                            labelAlign: 'top',
                            border:false
                        },
                        items: [{
                            items: [
                                SABSFactory.getCombo('destination',
                                    {fieldLabel: 'Destination'}),
								{
                                    xtype: 'hidden',
                                    id: 'resortcode'
                                },
                                {
                                    xtype: 'hidden',
                                    id: 'gateway'
                                },
                    SABSFactory.getDateGroup({
					time: true,
					startDateLabel: 'Pick-up Date',
					startTimeLabel: 'Pick-up Time',						
                                suffix: '-transfer'
                                }),
 				   SABSFactory.getDateGroup({
				     	time: true,
                        endDateLabel: 'Drop-off Date',
				        endTimeLabel: 'Drop-off Time',
                        suffix: '-transfer'
                        }),
                                SABSFactory.getTravellersGroup(true)
                            ]
                        }]
                    }]
                }, cfg)); //carhire
            }else if(type=='accommodation') {
                return new Ext.form.FormPanel(Ext.applyIf({
                    items: [{
                        layout: 'form',
                        border:false,
                        defaults: {
                            layout: 'form',
                            labelAlign: 'top',
                            border:false
                        },
                        items: [{
                            items: [
                                SABSFactory.getCombo('destination',
                                    {fieldLabel: 'Going To'}),
                                {
                                    xtype: 'hidden',
                                    id: 'resortcode'
                                },
                                {
                                    xtype: 'hidden',
                                    id: 'gateway'
                                },
                                SABSFactory.getDateGroup({
                                    startDateLabel: 'Checkin Date',
                                    endDateLabel: 'Checkout Date',
                                    suffix: '-accommodation',
                                    columns: 2
                                }),
                                SABSFactory.getAccommRoomGroup()
                            ]
                        }]
                    }]
                }, cfg));
            }else if(type=='holiday') {
                return new Ext.form.FormPanel(Ext.applyIf({
                    items: [{
                        layout: 'form',
                        border:false,
                        defaults: {
                            layout: 'form',
                            labelAlign: 'top',
                            border:false
                        },
                        items: [{
                            items: [
                                SABSFactory.getCombo('departure',
                                    {fieldLabel: 'Leaving From'}),
					            SABSFactory.getCombo('destGroup'),
                                {
                                    xtype: 'hidden',
                                    id: 'type'
                                },
                               /* SABSFactory.getCombo('destination',
                                    {fieldLabel: 'Going To'}),
                                {
                                    xtype: 'hidden',
                                    id: 'gateway'
                                },*/
                                SABSFactory.getDateGroup({
                                    startDateLabel: 'Departure Date',
                                    endDateLabel: 'Return Date',
                                    suffix: '-holiday',
                                    columns: 2
                                }),
                                SABSFactory.getFlexibleDatesCheckbox(),
                                // TODO: make sure this needs
                                // to be instantiated here
                                SABSFactory.getCombo('boardbasis'),
                                SABSFactory.getCombo('rating'),
                                SABSFactory.getTravellersGroup(true)
                            ]
                        }]
                    }]
                }, cfg));
            } else if (type=='transfer'){
				return new Ext.form.FormPanel(Ext.applyIf({
                    items: [{
                        layout: 'form',
                        border:false,
                        defaults: {
                            layout: 'form',
                            labelAlign: 'top',
                            border:false
                        },
			              items: [{
                            items: [
                                SABSFactory.getCombo('destination',
                                    {fieldLabel: 'Destination'}, 'transfer'),
                                {
                                    xtype: 'hidden',
                                    id: 'resortcode'
                                },
                                {
                                    xtype: 'hidden',
                                    id: 'gateway'
                                },
                                SABSFactory.getDateGroup({
					time: true,
					startDateLabel: 'Pick-up Date',
					startTimeLabel: 'Pick-up Time',						
                                suffix: '-transfer'
                                }),
				SABSFactory.getCombo('departure',
                                    {fieldLabel: 'Departure Airport'}),
			        {
                                xtype: 'checkbox',
                                // custom classes >
                                cls: 'micros-formelem micros-checkbox micros-directflights-checkbox',
                                ctCls: 'micros-formelem-ct micros-checkbox-ct micros-directflights-checkbox-ct',
                                itemCls: 'micros-formelem-item micros-checkbox-item micros-directflights-checkbox-item',
                                // < custom classes
                                hideLabel: true,
                                checked: true,
                                id: 'returnorsingle',
                                boxLabel: 'Return Journey',
                                listeners: {
                                	check: function(item, checked){
                                		if (checked){
                                		    Ext.getCmp('dategroup-transfer').show();
                                		} else {
                                		    Ext.getCmp('dategroup-transfer').hide();
                                		}
                                	}
                                }
                                },
 				SABSFactory.getDateGroup({
					time: true,
                                        endDateLabel: 'Departure Date',  
				        endTimeLabel: 'Departure Time',
                                        suffix: '-transfer'
                                }),
				SABSFactory.getTravellersGroup()	
                            ]
                        }
                        ]
                    }]
                }, cfg));	// transfer
			}
		} //width <300	
        switch(type){
            case 'contact':
                return new Ext.form.FormPanel(Ext.applyIf({
                    labelAlign: 'top',
                    //bodyStyle:'padding: 0px 0px 0px 10px',
                    buttons:[{text:'Submit'}],
                    items: [{ // personal details
                        layout: 'column',
                        bodyStyle: 'margin-bottom:10px',
                        defaults: {
                            border: false
                        },
                        items: [{
                            columnWidth: 0.15,
                            anchor: '0',
                            layout: 'form',
                            items: {
                                xtype: 'combo',
                                name: "Title",
                                fieldLabel: 'Title',
                                hiddenName:'Title',
                                store: new Ext.data.SimpleStore({
                                    fields: ['values','description'],
                                    data: [
                                        ['Mr', 'MR'], ['Mrs', 'MRS'],
                                        ['Ms', 'MS'], ['Miss', 'MISS']
                                    ]
                                }),
                                displayField:'description',
                                valueField:'values',
                                mode: 'local',
                                allowBlank: false,
                                anchor: '-10'
                            }
                        },{
                            columnWidth: 0.35,
                            anchor: '0',
                            layout: 'form',
                            items: [{
                                xtype: 'textfield',
                                name: 'Forename',
                                fieldLabel: 'Forename',
                                allowBlank: false,
                                maxLength: 17,
                                anchor: '-10'
                            }]
                        },{
                            columnWidth: 0.5,
                            anchor: '0',
                            layout: 'form',
                            items: {
                                xtype: 'textfield',
                                name: 'Surname',
                                fieldLabel: 'Surname',
                                allowBlank: false,
                                maxLength: 17,
                                anchor: '-10'
                            }
                        }]
                    },{ // two-sided address & contact info
                        layout: 'column',
                        defaults: {
                            border: false
                        },
                        items: [{ // address details
                            layout:'form',
                            anchor: '0',
                            columnWidth: 0.5,
                            items:[{
                                xtype: 'hidden',//'textfield',
                                name: 'House',
                                fieldLabel: 'House name/Number',
                                allowBlank: true,
                                maxLength: 30,
                                anchor: '-10'
                            },{
                                xtype: 'textarea',
                                name: 'Address',
                                fieldLabel: 'Address',
                                //allowBlank: false,
                                grow: false,
                                maxLength: 80,
                                anchor: '-10'
                            },{
                                xtype: 'textfield',
                                name: 'County',
                                fieldLabel: 'County',
                                allowBlank: true,
                                maxLength: 40,
                                anchor: '-10'
                            },{
                                xtype: 'textfield',
                                name: 'PostCode',
                                fieldLabel: 'Post code',
                                allowBlank: true,
                                maxLength: 10,
                                anchor: '-10'
                            }]
                        },{ // contact details
                            layout: 'form',
                            anchor: '0',
                            columnWidth: 0.5,
                            defaults: {
                                border: false
                            },
                            items:[{
                                xtype: 'textfield',
                                name: 'Email',
                                fieldLabel: 'Email',
                                allowBlank: true,
                                anchor: '-10'
                            },{
                                layout: 'column',
                                defaults: {
                                    border: false
                                },
                                items: [{
                                    columnWidth: 0.5,
                                    anchor: '0',
                                    layout: 'form',
                                    items: {
                                        xtype: 'textfield',
                                        name: 'Phone',
                                        fieldLabel: 'Phone',
                                        allowBlank: false,
                                        maskRe: /\d|\s/,
                                        anchor: '-10'
                                    }
                                },{
                                    columnWidth: 0.5,
                                    layout: 'form',
                                    anchor: '0',
                                    items: {
                                        xtype: 'textfield',
                                        name: 'Mobile',
                                        fieldLabel: 'Mobile',
                                        allowBlank: true,
                                        maskRe: /\d|\s/,
                                        anchor: '-10'
                                    }
                                }]
                            },{
                                xtype: 'textfield',
                                name: 'ContactTime',
                                fieldLabel: 'Contact time',
                                allowBlank: true,
                                anchor: '-10'
                            },{
                                xtype: 'textarea',
                                name: 'Comments',
                                fieldLabel: 'Comments',
                                allowBlank: true,
                                height:60,
                                grow: false,
                                anchor: '-10'
                            }]
                        }]
                    }]
                }, cfg));
            case 'flight':
                return new Ext.form.FormPanel(Ext.applyIf({
                    items: [{
                        layout: 'form',
                        style: {
                            borderBottom: '1px solid #99BBE8',
                            marginBottom: '10px',
                            marginRight: '10px'
                        },
                        items:[{
                            xtype: 'radiogroup',
                            // custom classes >
                            cls: 'micros-formelem micros-radiogroup micros-flighttype-radiogroup',
                            ctCls: 'micros-formelem-ct micros-radiogroup-ct micros-flighttype-radiogroup-ct',
                            itemCls: 'micros-formelem-item micros-radiogroup-item micros-flighttype-radiogroup-item',
                            // < custom classes
                            fieldLabel: 'Flight type',
                            id: 'flightType',
                            columns: 1,
                            //anchor: '50%',
                            items: [{
                                boxLabel: 'One way',
                                name: 'FlightType',
                                inputValue: 'O',
                                listeners: {
                                    check: flightTypeChange
                                }

                            },{
                                boxLabel: 'Return',
                                name: 'FlightType',
                                inputValue: 'R',
                                checked: true,
                                listeners: {
                                    check: flightTypeChange
                                }
                            }]
                        }]
                    }, Ext.applyIf({
                        items: [{                   //left side
                            items: [
                                SABSFactory.getCombo('departure',
                                    {fieldLabel: 'Leaving From'}),
                                SABSFactory.getCombo('destGroup',
                                    {fieldLabel: 'Going To'}),
                                 {
                                    xtype: 'hidden',
                                    id: 'type'
                                },
                                {
                                    xtype: 'hidden',
                                    id: 'gateway'
                                },
                            {
                                xtype: 'checkbox',
                                // custom classes >
                                cls: 'micros-formelem micros-checkbox micros-directflights-checkbox',
                                ctCls: 'micros-formelem-ct micros-checkbox-ct micros-directflights-checkbox-ct',
                                itemCls: 'micros-formelem-item micros-checkbox-item micros-directflights-checkbox-item',
                                // < custom classes
                                hideLabel: true,
                                id: 'DirectFlights',
                                boxLabel: 'Direct Flights Only'
                            }]
                        },{                         //right side
                            items: [
                                SABSFactory.getDateGroup({
                                    startDateLabel: 'Departure Date',
                                    endDateLabel: 'Return Date',
                                    suffix: '-flight'
                                }),
                                SABSFactory.getFlexibleDatesCheckbox(),

                                // TODO: make sure this needs
                                // to be instantiated here
                                new Ext.form.ComboBox({
                                    xtype: 'combo',
                                    // custom classes >
                                    cls: 'micros-formelem micros-combobox micros-seatclass-combobox',
                                    ctCls: 'micros-formelem-ct micros-combobox-ct micros-seatclass-combobox-ct',
                                    itemCls: 'micros-formelem-item micros-combobox-item micros-seatclass-combobox-item',
                                    // < custom classes
                                    fieldLabel: 'Seat class',
                                    hiddenName:'seatClass',
                                    store: new Ext.data.SimpleStore({
                                        fields: ['values','description'],
                                        data: [
                                            ['', 'Any'],
                                            ['E', 'Economy'],
                                            ['B', 'Business'],
                                            ['F', 'First']
                                        ]
                                    }),
                                    displayField:'description',
                                    valueField:'values',
                                    hideTrigger: false,
                                    mode: 'local',
                                    allowBlank: true,
                                    editable: false,
                                    triggerAction: 'all'
                                }),
                                SABSFactory.getTravellersGroup()
                            ]
                        }]
                    }, colCfg)]
                }, cfg));
            case 'holiday':
                return new Ext.form.FormPanel(Ext.applyIf({
                    items: [ Ext.applyIf({
                        items: [{                       //left side
                            items: [
                                SABSFactory.getCombo('departure'),
                                SABSFactory.getCombo('destGroup'),
                                 {
                                    xtype: 'hidden',
                                    id: 'type'
                                },
                                {
                                    xtype: 'hidden',
                                    id: 'gateway'
                                },
                                //{
                                    //layout: 'form',
                                    //labelAlign: 'left',
                                    //items: [
                                        SABSFactory.getCombo('boardbasis'),
                                        SABSFactory.getCombo('rating')
                                    //]
                                //}
                            ]
                        },{                             //rightside
                            items: [
                                SABSFactory.getDateGroup({
                                    startDateLabel: 'Departure Date',
                                    endDateLabel: 'Return Date',
                                    suffix: '-holiday'
                                }),
                            {
                                layout: 'form',
                                border: false,
                                items: [
                                    SABSFactory.getFlexibleDatesCheckbox(),
                                    SABSFactory.getTravellersGroup()
                                ]
                            }]
                        }
                        ]
                    }, colCfg) ]
                }, cfg)); // holiday
            case 'transfer':
                return new Ext.form.FormPanel(Ext.applyIf({
					
                    items: [ Ext.applyIf({
                        items: [{
                            // left side
                            items: [
								
                                SABSFactory.getCombo('departure'),
                                SABSFactory.getCombo('destination')
                            ]
                        },{
						
                            // right side
                            items: [
                                SABSFactory.getDateGroup({
                                    startDateLabel: 'Pickup Dates',
                                    endDateLabel: 'Dropoff Dates',
                                    suffix: '-transfer',
                                    time: true,
                                    startTimeLabel: 'Time',
                                    endTimeLabel: 'Time'
                                }),
                                SABSFactory.getTravellersGroup()
                            ]
                        }]
                    }, colCfg),
                        {
                             xtype: 'hidden',
                             id: 'type'
                        },
                        {
                            xtype: 'hidden',
                            id: 'resortcode'
                        },
                        {
                            xtype: 'hidden',
                            id: 'gateway'
                        }
                    ]
                }, cfg)); // transfer
				
            case 'carhire':
                return new Ext.form.FormPanel(Ext.applyIf({
                    items: [ Ext.applyIf({
                        items: [{   // left side
                            items: [
                                SABSFactory.getCombo('destination'),
                                {
                                    xtype: 'hidden',
                                    id: 'type'
                                },
                                {
                                    xtype: 'hidden',
                                    id: 'gateway'
                                }
                            ]
                        },{                             // right side
                            items: [
                                SABSFactory.getDateGroup({
                                    startDateLabel: 'Pickup Date',
                                    endDateLabel: 'Dropoff Date',
                                    suffix: '-carhire',
                                    time: true,
                                    startTimeLabel: 'Time',
                                    endTimeLabel: 'Time'
                                }),{
                                    xtype: 'numberfield',
                                    name: 'DriverAge',
                                    fieldLabel: 'Driver\'s age'
                                },
                                SABSFactory.getTravellersGroup()
                            ]
                        }]
                    }, colCfg),
			{
                            xtype: 'hidden',
                            id: 'resortcode'
                        }]
                }, cfg) ); // carhire
            case 'accommodation':
                return new Ext.form.FormPanel(Ext.applyIf({
                    items: [ Ext.applyIf({
                        items: [{                       //left side
                            items: [
                                SABSFactory.getCombo('destination'),
                                 {
                                    xtype: 'hidden',
                                    id: 'type'
                                },
                                {
                                    xtype: 'hidden',
                                    id: 'resortcode'
                                },
                                {
                                    xtype: 'hidden',
                                    id: 'gateway'
                                },
                                SABSFactory.getAccommRoomGroup()
                            ]
                        },{                             //rightside
                            items: [
                                SABSFactory.getDateGroup({
                                    startDateLabel: 'Checkin Date',
                                    endDateLabel: 'Checkout Date',
                                    suffix: '-accommodation'
                                })
                            ]
                        }]
                    }, colCfg) ]
                }, cfg) ); // accomodation
        }//switch
    }, //getForm
    // SEARCH RESULTS
    getTemplate: function(type, compositeType, subtype){
			var tpl;
			var imagePath = SABSFactory.IsFromOld ? '/sabs_consumer' : '';
			var costs = [
                    '<table>',
                    '<tpl if="Costs.length &gt; 0">',
                    '<tr>',
			'<th class="room-price" style="width: 90%;">Desc</th>',
                        '<th class="room-type">Cost</th>',
                    '</tr>',
                    '</tpl>',
                    '<tpl for="Costs">',
                        '<tr class="costs" >',
                            '<td class="room-price" style="width: 80%;">{CSTDescription}</td>',
                            '<td class="room-type">{CSTTotal}</td>',
                        '</tr>',
			'</tpl>',
			'<tr>',
			'<td class="room-price" style="width: 80%;">&nbsp;</td><td  style="text-align: right;"><strong> Total = {[SABS.Money(values.Price, values.Currency)]}</strong></td>',
			'</tr>',
                    '</table>'
                ].join('');

			var errata = [
                      '<table>',
                       '<tr>',
			'<td class="costs" colspan="2">',
	                '{Errata}',
			'</td>',
			'</tr>',
                     '</table>'
                ].join('');

        var basketButtons = function(type){
            if(!type){
             if(subtype === 'alts'){
                return  ['<div class="addToBasket" style="height:50px;">',
			'<a href="#" id="choosealt" class="bookbutton" style="height: 40px !important;border-top: 1px grey solid;padding-top: 10px;line-height: 15px">Choose this Alternative</a>',
			'</div>'
			].join('');
		    }else{  	    
            	    
                return  ['<div class="addToBasket" style="height: <tpl if="Booking != &quot;Cannot Book&quot;">100</tpl><tpl if="Booking === &quot;Cannot Book&quot;">50</tpl>px;">',
						'<a href="#" id="basket" style="height: 40px;padding-top: 10px;">Add to Basket</a>',
						'<tpl if="Booking != &quot;Cannot Book&quot;">',
						'<a href="#" id="book" class="bookbutton" style="height: 40px !important;border-top: 1px grey solid;padding-top: 10px;">Book Now!</a>',
						'</tpl>',
						'</div>'
						].join('');
		    }
            } else if(type == 'basket'){
            		if(subtype == 'booking'){
							return ['<div class="addToBasket" style="height: 150px;font: bold 11px tahoma,verdana,helvetica;padding-top: 10px;">', //<a href="#" id="basket" style="height: 50px;" >Remove</a>
						
						'<tpl if="Booking === &quot;init&quot;">',
						'Booking <br /><img src="http://images.sabsagent.com/images/sabs2/loading-large.gif" />',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;Ready to Book&quot;">',
						'Ready to Book',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;stage:1&quot;">',
						'Confirming availability <br /><br /><img src="http://images.sabsagent.com/images/sabs2/loading-large.gif" />',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;stage:2&quot;">',
						'Confirming price <br /><br /><img src="http://images.sabsagent.com/images/sabs2/loading-large.gif" />',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;stage:3&quot;">',
						'Booking <br /><br /><img src="http://images.sabsagent.com/images/sabs2/loading-large.gif" />',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;inputrequired&quot;">',
						'Please enter the required details',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;readytobook&quot;">',
						'Cost breakdown updated.<br />',
						'<br />Click below to continue to the payment screen.<br />',
						'<br /><a class="fake-button" id="book-item-action" href="#"><span>&nbsp;</span>Pay now </a>',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;error&quot;">',
						'Booking Error',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;error-digest&quot;">',
						'An Error has occured with your booking. <br />Please start your search again',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;Cannot Book&quot;">',
						'Cannot Book Online',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;alternatives&quot;">',
						'No availability can be found',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;Paid&quot;">',
						'Payment Accepted',
						'<br /><br /><img src="http://images.sabsagent.com/images/sabs2/loading-large.gif" />',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;failed-nonpayment&quot;">',
						'Failed non-payment',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;failed-nonpayment-timeout&quot;">',
						'Your payment may have not completed in time.',
						'<br />We are completing a final check.<br />',
						'<br /><br /><img src="http://images.sabsagent.com/images/sabs2/loading-large.gif" />',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;Sorry, credit card authentication failed - please check with your bank.&quot;">',
						'Sorry, credit card authentication failed - please check with your bank.',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;Sorry, you used a test credit card number- please check with your bank.&quot;">',
						'Sorry, you used a test credit card number - please check with your bank.',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;Insufficient parameters supplied from credit card authentication.&quot;">',
						'Insufficient parameters supplied from credit card authentication.',
						'</tpl>',
						
						
						'<tpl else if="Booking === &quot;failed-failedtobook&quot;">',
						'Failed to book<br />',
						'Your payment has been refunded.',
						'</tpl>',

						'<tpl else if="Booking === &quot;failed-failedtobook-nopayment&quot;">',
						'Failed to book<br /><br />',
						'Your payment may have been held up by the payment provider.<br />',
						'</tpl>',
						
						'<tpl else if="Booking === &quot;already_booked&quot;">',
						'Item already booked.',
						'</tpl>',						
						
						'<tpl else if="Booking === &quot;already_booked_failed&quot;">',
						'This item failed to book. Please search for an alternative of contact the agent.',
						'</tpl>',	
						
						
						'<tpl else if="Booking === &quot;Awating Payment Confirmation&quot;">',
						'Awaiting Payment Confirmation<br /><br /><img src="http://images.sabsagent.com/images/sabs2/loading-large.gif" />',
						
						'<br /><br /><a class="fake-button" id="book-item-action2" href="#"><span>&nbsp;</span>Pay now</a>',
						
						'</tpl>',

						'<tpl else if="Booking === &quot;complete&quot;">',
						'Payment Accepted<br /><br />',
						'Finalising Booking<br /><br />',
						
						'<tpl else if="BookingRef == &quot;&quot;">',
						'<img src="http://images.sabsagent.com/images/sabs2/loading-large.gif" />',
						'</tpl>',
						
						'<tpl else if="BookingRef != &quot;&quot;">',
						'Your Booking Reference: <br /> {BookingRef} <br /><br />An email has been sent to you containing all important information.',
						'</tpl>',
						
						'</tpl>',
						
						'<tpl else if="Booking === &quot;&quot;">',
						'Ready to Book',
						'</tpl>',
												
						'</div>'
					].join('');
		   }else{
				  return ['<div class="addToBasket" style="height: 50px;"><a href="#" id="basket" style="height: 50px;" >Remove</a></div>'];
			
		   	}
			
			} else if(type == 'landing'){
                return '';
            }
        }(compositeType);

        var pricing = [
            '<div class="pricing">',
            '<tpl if="DisplayPrice !== &quot;false&quot;">',
			'<p class="totalTitle">Total Price</p>',
                '<p class="priceLabel">',
				'<tpl if="FinalPrice <= &quot;0&quot;">',
				'<span id="estprice">From</span>',
				'</tpl>',
				
				'<tpl if="FinalPrice &gt; &quot;0&quot;">',
				'<span id="estprice">&nbsp;&nbsp;&nbsp;&nbsp;</span>',
				'</tpl>',
				
				'<span class="totalPrice" id="totalprice">{[SABS.Money(values.Price, values.Currency)]}</span>',
                '</p>',
                  '<tpl if="DiscountID === &quot;0&quot; || DiscountID === &quot;&quot;">',
                '<p class="priceLabel">',
                    'Adult Price from<br/>',
                    '<span class="normalPrice">{[SABS.Money(values.ADTPrice, values.Currency)]}</span> pp',
                '</p>',
                '<p class="priceLabel">',
                    'Child Price from<br/>',
                    '<span class="normalPrice">{[SABS.Money( (values.CHDPrice == "" || values.CHDPrice == 0) ? values.ADTPrice : values.CHDPrice, values.Currency)]}</span> pp',
                '</p>',      
                '</tpl>',
				'</tpl>',

				'</div>'
        ].join('');

	    var carPricing = [
            '<div class="pricing">',
                '<p class="totalTitle">Total Price</p>',
                '<p class="priceLabel totalCarPrice">',
                    // TODO: price should refect the search type
                '<tpl if="FinalPrice <= &quot;0&quot;">',
				'<span id="estprice">From</span>',
				'</tpl>',
				
				'<tpl if="FinalPrice &gt; &quot;0&quot;">',
				'<span id="estprice">&nbsp;&nbsp;&nbsp;&nbsp;</span>',
				'</tpl>',

					'<span class="totalPrice">{[SABS.Money(values.Price, values.Currency)]}</span>',
                '</p>',
            '</div>'
        ].join('');

        var validFrom = [
            '<div class="validFrom">',
                'Note that these prices are regularly updated and are subject to change at time of booking.<br />',
                'The total price will always be displayed to you prior to purchase.',
            '</div>'
        ].join('');

        var disclaimer = [
            ' '
        ].join('');

        // Transport uses a different format scandate !
        // TODO just change the mapping in getRecord rather than doing this.
        var carValidFrom = [
            '<div class="validFrom">',
                'Note that these prices are regularly updated and are subject to change at time of booking.<br />',
                'The total price will always be displayed to you prior to purchase.',
           '</div>'
        ].join('');

        var logo = [
            '<div class="logo">',
               '<tpl if="showIcons">',
                    '<img src="http://images.sabsagent.com/images/TourOp/{Operator}.gif" width="88" height="22" title="{OperatorFull}" alt="{OperatorFull}" />',
                '</tpl>',
            '</div>'
            ].join('');

        // The header for accommodation only and packages
        var accommHeader = [
            '<div class="header">',
                '<div class="resort">',
                    '{ResortName}',
                '</div>',
                logo,
                '<tpl if="typeof Nights !== &quot;undefined&quot;">',
                    '<div class="nights">{Nights}nts</div>',
                '</tpl>',
                '<div style="clear: both"></div>',
            '</div>'
        ].join('');

        var carImage = [
            '<tpl if="typeof ProductImagePath !== &quot;undefined&quot; &amp;&amp; ProductImagePath.length &gt; 0">',
                '<img src="{ProductImagePath}" width="75" alt="Vehicle image"/>',
            '</tpl>',
            '<tpl if="typeof ProductImagePath === &quot;undefined&quot; || ProductImagePath.length === 0">',
                '<img src="http://images.sabsagent.com/images/hotel_bw.gif" width="80" height="60" alt="No image available"/>',
            '</tpl>'
        ].join('');

        var flightTableHeader = function(icon) {
            return [
                '<tr>',
                    (icon ? '<th class="icon"></th>' : ''),
                    '<th class="from">From</th>',
                    '<th class="to">To</th>',
                    '<th class="date">Date</th>',
                    '<th class="depart">Depart</th>',
                    '<th class="arrive">Arrive</th>',
                '</tr>'
            ].join('');
        };

        switch(type){
				
				
            case 'flight':
                var basicFlightDetailsOut = [
                        '<tr>',
                            '<td class="from">{DepPointOutFull}</td>',
                            '<td class="to">{ArrPointOutFull}</td>',
                            '<td class="date">{DateOut:date("d-M-y")}</td>',
                            '<td class="depart">{DepTimeOut:date("H:i")}</td>',
                            '<td class="arrive">{ArrTimeOut:date("H:i")}</td>',
                        '</tr>'
                ].join('');

                var basicFlightDetailsIn = [
                    '<tr>',
                        '<td class="from">{ArrPointOutFull}</td>',
                        '<td class="to">{ArrPointInFull}</td>',
                        '<td class="date">{DateIn:date("d-M-y")}</td>',
                        '<td class="depart">{DepTimeIn:date("H:i")}</td>',
                        '<td class="arrive">{ArrTimeIn:date("H:i")}</td>',
                    '</tr>'
                ].join('');

                var legFlightDetails = function(direction) {
                    return [
                        '<tpl for="LegDetails">',
                            '<tpl if="direction === &quot;' + direction + '&quot;">',
                                '<tr>',
                                    '<td class="from">{depPointFull}</td>',
                                    '<td class="to">{arrPointFull}</td>',
                                    '<td class="date">{dateDep:date("d-M-y")}</td>',
                                    '<td class="depart">{timeDep:date("H:i")}</td>',
                                    '<td class="arrive">{timeArr:date("H:i")}</td>',
                                '</tr>',
                            '</tpl>',
                        '</tpl>'
                    ].join('');
                };

                tpl = [
                    '<div class="results">',
                        '<div class="header">',
                            '<div class="resort">',
                                '{DepPointOutFull} to {ArrPointOutFull}',
                            '</div>',
                            logo,
                            '<tpl if="Nights != 0">',
                                '<div class="nights">',
                                    '{Nights}nts',
                                '</div>',
                            '</tpl>',
                        '</div>',

                        '<div class="left">',
                            '<div class="title">',
                                'Outbound Journey {RecType}',
                            '</div>',
                            '<div class="details">',
                                '<table>',
                                flightTableHeader(),
                                '<tpl if="LegDetails.length === 0">',
                                    basicFlightDetailsOut,
                                '</tpl>',
                                '<tpl if="LegDetails.length !== 0">',
                                    legFlightDetails('O'),
                                '</tpl>',
                                '</table>',
                            '</div>',

                            '<tpl if="Nights &gt; 0">',
                                '<div class="title">',
                                    'Inbound Journey',
                                '</div>',
                                '<div class="details">',
                                    '<table>',
                                    flightTableHeader(),
                                    '<tpl if="LegDetails.length === 0">',
                                        basicFlightDetailsIn,
                                    '</tpl>',
                                    '<tpl if="LegDetails.length !== 0">',
                                        legFlightDetails('I'),
                                    '</tpl>',
                                    '</table>',
                                '</div>',
                            '</tpl>',

							
							'<tpl if="this.exists(Costs)">',
						
							'<div class="title">',
                                'Detailed Cost beakdown',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							costs,
							  '</div>',
							  
                            '</tpl>',
							
							'<tpl if="this.exists(Errata)">',
						
							'<div class="title">',
                             'Important Information',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							errata,
							'</div>',
							  
                            '</tpl>',
							
							
					        validFrom,
                            disclaimer,
                        '</div>',

                        '<div class="right">',
                            pricing,
                            basketButtons,
                            '<div style="clear: both"></div>',
                        '</div>',

                        '<div style="clear: both"></div>',
                    '</div>'            
                ];
                break;  
            case 'holiday':
                var flightDetails = [
                    '<table>',
                        flightTableHeader(true),
                        '<tr>',
                            '<td><img src="',
							imagePath,
							'/templates/images/flight_outbound.gif" width="20" height="20" alt="" /></td>',
                            '<td>{DepPointOutFullIATA}</td>',
                            '<td>{ArrPointOutFullIATA}</td>',
                            '<td>{DateOut:date("d-M-y")}</td>',
                            '<td>{DepTimeOut:date("H:i")}</td>',
                            '<td>{ArrTimeOut:date("H:i")}</td>',
                        '</tr>',
                        '<tr>',
                            '<td><img src="',
							imagePath,
							'/templates/images/flight_inbound.gif" width="20" height="20" alt="" /></td>',
                            '<td>{ArrPointOutFullIATA}</td>',
                            '<td>{ArrPointInFullIATA}</td>',
                            '<td>{DateIn:date("d-M-y")}</td>',
                            '<td>{DepTimeIn:date("H:i")}</td>',
                            '<td>{ArrTimeIn:date("H:i")}</td>',
                        '</tr>',
                    '</table>'
                ].join('');

	 			tpl =  ['<div class="results">',
                            	accommHeader,
								'<div class="left">',
								'<div class="brochure">',
								'<div class="rating">',
								'<img src="',
								imagePath,
								'/templates/images/stars_{Rating}.png" width="100" height="23" alt="{Rating} star rating" />',
								'</div>',

                                '<p class="hotel-name">',
                                    '<b>{HotelName}</b> - {BoardBasisFull}',
                                '</p>',
                                '<p>',
                                    '<a href="#" id="brochure">Click here for brochure details</a>',
                                '</p>',

                            '</div>',

                            '<div class="title">',
                                'Flight Details',
                            '</div>',
                            '<div class="details">',
                                flightDetails,
                            '</div>',
							
							
								'<tpl if="this.exists(Costs)">',
						
							'<div class="title">',
                                'Detailed Cost beakdown',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							costs,
							  '</div>',
							  
                            '</tpl>',
							
							'<tpl if="this.exists(Costs)">',
						
							'<div class="title">',
                             'Important Information',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							errata,
							'</div>',
							  
                            '</tpl>',
							
                            validFrom,
                            disclaimer,
                        '</div>',

                        '<div class="right">',
                            pricing,
                            basketButtons,
                            '<div style="clear: both"></div>',
                        '</div>',

                        '<div style="clear: both"></div>',
                    '</div>'
                ];
				
                break;
            case 'transfer':
                tpl = [
                    '<div class="results">',
                        '<div class="header">',
                            '<div class="car-type">{ProductType}</div>',
                            logo,
                        '</div>',
                        '<div class="left">',
                            '<div class="brochure">',
                                carImage,
                                '<p>{ProductDescription}</p>',
                            '</div>',
                            
                             '<div class="title">',
                                'Transfer Dates',
                            '</div>',
                            '<div class="details">',
                                '<table>',
                                    '<tr>',
                                        '<th class="carhire-class">Date Out</th>',
                                        '<tpl if="this.exists(DateIn)">',
                                        '<th class="carhire-model">Date In</th>',
                                             '</tpl>',
                                        '</tr>',
                                    '<tr>',
                                        '<td>{DateOut:date("d-M-y")}</td>',
                                        '<td>{DateIn:date("d-M-y")}</td>',
                                        '</tr>',
                                '</table>',
                                 '</div>',
                            
                            '<div class="title">',
                                'Transfer Details',
                            '</div>',
                            '<div class="details">',
                                '<table>',
                                    '<tr>',
                                        '<th class="transfer-type">Type</th>',
                                        '<th class="transfer-time">Transfer Time</th>',
                                        '<th class="max-passengers">Max Passengers</th>',
                                    '</tr>',
                                    '<tr>',
                                        '<td>{ProductType}</td>',
                                        '<td>{TransferMinutes}</td>',
                                        '<td>{MaxPax}</td>',
                                    '</tr>',
                                '</table>',
                            '</div>',
							
							
									'<tpl if="this.exists(Costs)">',
						
							'<div class="title">',
                                'Detailed Cost beakdown',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							costs,
							  '</div>',
							  
                            '</tpl>',
							
							'<tpl if="this.exists(Errata)">',
						
							'<div class="title">',
                             'Important Information',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							errata,
							'</div>',
							  
                            '</tpl>',
							
                            carValidFrom,
                            disclaimer,
							
                        '</div>',

                        '<div class="right">',
                            carPricing,
                            basketButtons,
                            '<div style="clear: both"></div>',
                        '</div>',

                        '<div style="clear: both"></div>',
                    '</div>'
                ];
                break;
            case 'carhire':
                tpl = [
                    '<div class="results">',
                        '<div class="header">',
                            '<div class="car-type">{Model}</div>',
                            logo,
                        '</div>',
                        '<div class="left">',
                            '<div class="brochure">',
                                carImage,
                                '<p>{ProductDescription}</p>',
                            '</div>',
                            
                            
                             '<div class="title">',
                                'Hire Details',
                            '</div>',
                            '<div class="details">',
                                '<table>',
                                    '<tr>',
                                        '<th class="carhire-class">Date From</th>',
                                        '<th class="carhire-model">Date Untill</th>',
                                        '</tr>',
                                    '<tr>',
                                        '<td>{DateOut:date("d-M-y")}</td>',
                                        '<td>{DateIn:date("d-M-y")}</td>',
                                        '</tr>',
                                '</table>',
                                 '</div>',
                            
                            '<div class="title">',
                                'Car Details',
                            '</div>',
                            '<div class="details">',
                                '<table>',
                                    '<tr>',
                                        '<th class="carhire-class">Car Class</th>',
                                        '<th class="carhire-model">Car Model</th>',
                                        '<th class="carhire-passengers">Passengers</th>',
                                      '</tr>',
                                    '<tr>',
                                    
                                        '<td>{AccrissClass}</td>',
                                        '<td>{Model}</td>',
                                        '<td>{MaxPax}</td>',
                                        '</tr>',
                                '</table>',

                                '<table>',
                                    '<tr>',
                                        '<th class="carhire-aircon">Air Con</th>',
                                        '<th class="carhire-automatic">Automatic</th>',
                                        '<th class="carhire-doors">Doors</th>',
                                        '<th class="carhire-luggage">Luggage (Large/Small)</th>',
                                    '</tr>',
                                    '<tr>',
                                        '<td>{Aircon}</td>',
                                        '<td>{Auto}</td>',
                                        '<td>{Doors}</td>',
                                        '<td>{LrgLuggage} / {SmlLuggage}</td>',
                                    '</tr>',
                                '</table>',

                            '</div>',
							
							
									'<tpl if="this.exists(Costs)">',
						
							'<div class="title">',
                                'Detailed Cost beakdown',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							costs,
							  '</div>',
							  
                            '</tpl>',
							
							'<tpl if="this.exists(Errata)">',
						
							'<div class="title">',
                             'Important Information',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							errata,
							'</div>',
							  
                            '</tpl>',
							
                            carValidFrom,
                            disclaimer,
                        '</div>',

                        '<div class="right">',
                            carPricing,
                            basketButtons,
                            '<div style="clear: both"></div>',
                        '</div>',

                        '<div style="clear: both"></div>',
                    '</div>'
                ];
                break;  
            case 'accommodation':
                var summaryDetails = [
                    '<table>',
                    '<tr>',
                        '<th class="check-in-date">Check-in Date</th>',
                        '<th class="check-out-date">Check-out Date</th>',
                        '<th class="nights">Nights</th>',
                    '</tr>',
                    '<tr>',
                        '<td class="check-in-date">{ArrDateOut:date("d-M-y")}</td>',
                        '<td class="check-out-date">{DepDateIn:date("d-M-y")}</td>',
                        '<td class="nights">{Nights}</td>',
                    '<tr>',
                    '</table>'
                ].join('');

                var roomDetails = [
                    '<table>',
                    '<tr>',
                        '<th class="room-price">Price</th>',
                        '<th class="room-type">Room Type</th>',
                    '</tr>',
                    '<tpl for="RoomDetails">',
                        '<tr>',
                            '<td class="room-price">{MinPrice:ukMoney}</td>',
                            '<td class="room-type">{RoomDesc}</td>',
                        '<tr>',
                    '</tpl>',
                    '</table>'
                ].join('');

                tpl = [
                    '<div class="results">',
                        accommHeader,

                        '<div class="left">',
                            '<div class="brochure">',
                                '<div class="rating">',
                                    '<img src="',
									imagePath,
									'/templates/images/stars_{Rating}.png" width="100" height="23" alt="{Rating} star rating" />',
                                '</div>',

                                '<p class="hotel-name">',
                                    '<b>{HotelName}</b> - {BoardBasisFull}',
                                '</p>',
                                '<p>',
                                    '<a href="#" id="brochure">Click here for brochure details</a>',
                                '</p>',

                            '</div>',

                            '<div class="title">',
                                'Booking Details',
                            '</div>',

                            '<div class="details">',
                                summaryDetails,
                                roomDetails,
						    '</div>',
							
							'<tpl if="this.exists(Costs)">',
						
							'<div class="title">',
                                'Detailed Cost beakdown',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							costs,
							  '</div>',
							  
                            '</tpl>',
							
							'<tpl if="this.exists(Errata)">',
						
							'<div class="title">',
                             'Important Information',
                            '</div>',
                            '<div class="details" id="costtemplate">',
							errata,
							'</div>',
							  
                            '</tpl>',
							
							validFrom,
                            disclaimer,
                        '</div>',
                        '<div class="right">',
                            pricing,
							basketButtons,
                            '<div style="clear: both"></div>',
                        '</div>',

                        '<div style="clear: both"></div>',
                    '</div>'
                ];
                break;
            case 'basket':
            case 'landing':
                tpl = [
					'<tpl if="RecType == &quot;JNY&quot; || RecType == &quot;FLT&quot;">',
                        SABSFactory.getTemplate('flight', type, subtype),
                    '</tpl>',
                    // Car hire and transfers both use the TRS record type.
                    // We assume that Car Hire will have the ProductType
                    // field set to "Car Hire".
                    '<tpl if="RecType == &quot;TRS&quot; &amp;&amp; ProductType == &quot;Car Hire&quot;">',
                        SABSFactory.getTemplate('carhire', type, subtype),
                    '</tpl>',
                    '<tpl if="RecType == &quot;TRS&quot; &amp;&amp; ProductType !== &quot;Car Hire&quot;">',
                        SABSFactory.getTemplate('transfer', type, subtype),
                    '</tpl>',
                    '<tpl if="RecType == &quot;ACC&quot;">',
                        SABSFactory.getTemplate('accommodation', type, subtype),
                    '</tpl>',
                    '<tpl if="RecType == &quot;HOL&quot;">',
                        SABSFactory.getTemplate('holiday', type, subtype),
                    '</tpl>'
                ];
				if (subtype === 'booking'){
						tpl.unshift(['<div class="results"><div class="header" style="font-size: 110%;"><p>Below are your' ,
						'<tpl if="RecType == &quot;JNY&quot; || RecType == &quot;FLT&quot;"> Flight </tpl>', 
						'<tpl if="RecType == &quot;TRS&quot; &amp;&amp; ProductType == &quot;Car Hire&quot;"> Car Hire </tpl>',
						 '<tpl if="RecType == &quot;TRS&quot; &amp;&amp; ProductType !== &quot;Car Hire&quot;"> Transfer </tpl>',
						'<tpl if="RecType == &quot;ACC&quot;"> Accommodation </tpl>',
						'<tpl if="RecType == &quot;HOL&quot;"> Holiday </tpl>',
						 'details.</p><p>To continue booking, please click the \'Book\' button.<br />When prompted please fill in the travellers details.</p></div></div>'
						].join(''));
                }
				break;
        }
        if(compositeType){
            return tpl.join('');
        } else {
            return new Ext.XTemplate(
					'{[Costs=""]}',
                '<tpl for=".">',
                    '<div class="product-wrap">',
                        tpl.join(''),
                    '</div>',
                '</tpl>',
				{
		  exists: function(o){
			   return typeof o != 'undefined' && o !== null && o!=='';
		  }
	}

             );
        }

    },
    getRecord: function(type){
        var time = [
            {name: 'DepDateOut', type: 'date', dateFormat: 'ymd'},
            {name: 'DepTimeOut', type: 'date', dateFormat: 'hi'},
            {name: 'ArrDateOut', type: 'date', dateFormat: 'ymd'},
            {name: 'ArrTimeOut', type: 'date', dateFormat: 'hi'},
            {name: 'DepDateIn', type: 'date', dateFormat: 'ymd'},
            {name: 'DepTimeIn', type: 'date', dateFormat: 'hi'},
            {name: 'ArrDateIn', type: 'date', dateFormat: 'ymd'},
            {name: 'ArrTimeIn', type: 'date', dateFormat: 'hi'},
            {name: 'DateIn', type: 'date', convert: function(v,r) {
                if ( typeof r.DepDateIn !== 'undefined' && r.DepDateIn.length > 0 ) {
                    return Date.parseDate(r.DepDateIn, 'ymd');
                }
                else if ( typeof r.ArrDateIn !== 'undefined' && r.ArrDateIn.length > 0 ) {
                    return Date.parseDate(r.ArrDateIn, 'ymd');
                }
            }},
            {name: 'DateOut', type: 'date', convert: function(v,r) {
                if ( typeof r.DepDateOut !== 'undefined' && r.DepDateOut.length > 0 ) {
                    return Date.parseDate(r.DepDateOut, 'ymd');
                }
                else if ( typeof r.ArrDateOut !== 'undefined' && r.ArrDateOut.length > 0 ) {
                    return Date.parseDate(r.ArrDateOut, 'ymd');
                }
            }}
        ];
        var price = [
            {name: 'ADTPrice', type: 'float'},
            {name: 'CHDPrice', type: 'float'},
            {name: 'Price', type: 'float', convert: this.getItemPrice},
            {name: 'FinalPrice', type: 'float', defaultValue: '0'}
		];
        var loc = [
            {name: 'DepPointOutFullIATA'}, 
            {name: 'DepPointOutFull'}, 
            {name: 'DepPointOut'}, 
            {name: 'ArrPointOutFullIATA'},
            {name: 'ArrPointOutFull'}, 
            {name: 'ArrPointOut'},
            {name: 'DepPointInFullIATA'}, 
            {name: 'DepPointInFull'}, 
            {name: 'DepPointIn'}, 
            {name: 'ArrPointInFullIATA'},
            {name: 'ArrPointInFull'}, 
            {name: 'ArrPointIn'}
        ];
        var deflt = [
            {name: 'TravelCode'},
            {name: 'Operator'},
            {name: 'OperatorFull'},
            {name: 'RecType'},
            {name: 'Nights', type: 'int', convert: function(v,r) {
                if ( typeof r.Nights !== 'undefined' && r.Nights.length > 0 ) {
                    return r.Nights;
                }
                else {
                    // If there's no Nights field then try to calculate it
                    var from = Date.parseDate(r.DepDateOut, 'ymd');
                    var to = Date.parseDate(r.ArrDateIn, 'ymd');

                    if ( typeof from !== 'undefined' && typeof to !== 'undefined' ) {
                        return (to - from) / MSECS_IN_DAY;
                    }
                }
                // We don't have the fields needed to calculate
                return 0;
            }},
            {name: 'Currency'},
            {name: 'ScanDate', type: 'date', dateFormat: 'ymd'},
            {name: 'CarScanDate', mapping: 'ScanDate', type: 'date', dateFormat: 'y/m/d'},
            {name: 'ScanTime', type: 'date', dateFormat: 'Hi'},
            {name: 'showIcons', type: 'boolean', convert: this.getShowIcons},
            {name: 'Booking', defaultValue: 'Ready to Book', convert: this.allowBooking},
			{name: 'Errata', defaultValue: 'No information', convert: this.appendErrata},
			{name: 'DisplayPrice', defaultValue: 'true'},
			{name: 'DiscountID', defaultValue: 'true'}
		];

        switch(type){
            case 'flight':
                return deflt.concat(loc, price, time,
                    {name: 'FlightNumIn'},
                    {name: 'FlightNumOut'},
                    {name: "LegDetails", defaultValue: [], convert: this.expandLegDetails}
                );
            case 'holiday':
                return deflt.concat(loc, price, time,
                	 {name: 'TravelCode'},
                    {name: 'HolidayCode'},
                    {name: 'HotelName'},
                    {name: 'ResortName'},
                    {name: 'BoardBasisFull'},
                    {name: 'Rating', type: 'int'}

                );
            case 'accommodation':
                return deflt.concat(loc, price, time,
                	 {name: 'TravelCode'},
                    {name: 'HolidayCode'},
                    {name: 'HotelName'},
                    {name: 'BoardBasisFull'},
                    {name: 'Rating', type: 'int'},
                    {name: 'RoomsCount'},
                    {name: 'ResortName'},
                    {name: 'ArrDateOut', type: 'date', dateFormat: 'ymd'},
                    {name: 'DepDateIn', type: 'date', dateFormat: 'ymd'},
                    {name: 'ArrDateIn', type: 'date', dateFormat: 'ymd'},
		    {name: "RoomDetails", defaultValue: [], convert: this.expand}
                );
            case 'transfer':
                return deflt.concat(loc, price, time,
                    {name: 'ProductType'},
                    {name: 'ProductDescription'},
                    {name: 'TransferMinutes', type: 'int'},
                    {name: 'ProductImagePath'},
                    {name: 'MaxPax'}
                );
            case 'carhire':
                return deflt.concat(loc, price, time,
                    {name: 'ProductType'},
                    {name: 'LrgLuggage'},
                    {name: 'SmlLuggage'},
                    {name: 'ProductImagePath'},
                    {name: 'ProductDescription'},
                    {name: 'MaxPax'},
                    {name: 'AccrissClass'},
                    {name: 'Model'},
                    {name: 'CurrencyCode'},
                    {name: 'Doors'},
                    {name: 'Aircon', defaultValue: '', convert: this.expandBooleanToEnglish},
                    {name: 'Auto', defaultValue: '', convert: this.expandBooleanToEnglish}
					);
            case 'basket':
            case 'landing':
                return deflt.concat(loc, price, time,
                    // Accommodation/holiday
                    {name: 'TravelCode'},
                    {name: 'HolidayCode'},
                    {name: 'HotelName'},
                    {name: 'ResortName'},
                    {name: 'BoardBasisFull'},
                    {name: 'FlightNumIn'},
                    {name: 'FlightNumOut'},
                    {name: 'Rating', type: 'int'},
                    {name: "RoomDetails", defaultValue: [], convert: this.expand},
                    {name: "Costs", defaultValue: [], convert: this.expand},
					// Car Hire/Transfers
                    {name: 'ProductType'},
                    {name: 'LrgLuggage'},
                    {name: 'SmlLuggage'},
                    {name: 'ProductImagePath'},
                    {name: 'TransferMinutes', type: 'int'},
                    {name: 'ProductDescription'},
                    {name: 'MaxPax'},
  			        {name: 'BookingRef'},
                    {name: 'Model'},
                    {name: 'Doors'},
					  {name: 'Type'},
                    {name: 'AccrissClass'},
                    {name: 'Aircon', defaultValue: '', convert: this.expandBooleanToEnglish},
                    {name: 'Auto', defaultValue: '', convert: this.expandBooleanToEnglish},
                    // Flights
                    {name: "LegDetails", defaultValue: [], convert: this.expandLegDetails}

		        );
        }
    },
    getShowIcons: function(v,record){
	if (record.Icons.indexOf("N") === -1) {
            return true;
       } else {
            return false;
       }
    },
	allowBooking: function(v,r){
		if (r.Booking && r.Booking !== ''){
			return r.Booking;
		}else{
			if (r.Icons.indexOf("s") === -1) {
				return 'Cannot Book';
			} else {
				return 'Ready to Book';
			}
		}
    },
	appendErrata: function(v,r){
		var errata = '';
		if (Ext.isArray(r.Costs)){
		  var i=0, l=r.Costs.length, f;  
		  while (i<l) {
		      if (r.Costs[i].ErrataCST){
			 	 errata = errata + r.Costs[i].ErrataCST.toString();
			  }
		  i++;
		}
	}
	return errata;
	},
    // Generic way of accessing the "total" price for an item
    getItemPrice: function(v,r) {
		if (  typeof r.FinalPrice !== 'undefined' && r.FinalPrice && r.FinalPrice != '0'){
		  return parseFloat( r.FinalPrice );
		}
		else if ( typeof r.Costs !== 'undefined' && Ext.isArray(r.Costs) ) {
			var total = 0;
			var ccs = 0;
			Ext.each(r.Costs, function(o){
				if (o.CSTTotal.indexOf('%') >= 1){
					ccs = parseFloat(o.CSTTotal.replace('%', ''));
				} else {
					total =  total + parseFloat(o.CSTTotal) ;
				}
			});
			
			var MerchantFee = parseInt(total * ccs, 10);
			var newTotal = parseInt(total * 100 + MerchantFee, 10)/100;
			
			
			return newTotal.toFixed(2);
		}	
        else if ( typeof r.EstPrice !== 'undefined' && r.EstPrice ) {
        	if (r.EstPrice > 0){
        	    return parseFloat( r.EstPrice );
        	}else{
        	    var params = Ext.decode(SessionDataProvider.getParams());
        	    var Adults = params.Adults || 0;
        	    var Children = params.Children || 0;
        	    return parseFloat( (r.ADTPrice * Adults) + (r.CHDPrice * Children));
        	}       
            
        }
        else if ( typeof r.ReturnPrice !== 'undefined' && r.ReturnPrice ) {
            return parseFloat( r.ReturnPrice );
        }
        else if ( typeof r.SinglePrice !== 'undefined' && r.SinglePrice ) {
            return	 parseFloat( r.SinglePrice );
        }
        else {
            return 0;
        }
    },
    expandBooleanToEnglish: function(v, r) {
        if ( typeof v == 'undefined' || !v ) {
            return 'No';
        }
        else {
            return 'Yes';
        }
    },
    expandLegDetails: function(v, r){
        var legs = [];
        if(Ext.isArray(v)) {
            var i=0, l=v.length, f;
            while (i<l) {
                legs[i] = {};
                for(f in v[i]){
                    switch (f){
                        case "dateDep":
                            legs[i][f] = Date.parseDate(v[i][f], 'ymd');
                            break;
                        case "timeDep":
                            legs[i][f] = Date.parseDate(v[i][f], 'Hi');
                            break;
                        case "dateArr":
                            legs[i][f] = Date.parseDate(v[i][f], 'Ymd');
                            break;
                        case "timeArr":
                            legs[i][f] = Date.parseDate(v[i][f], 'Hi');
                            break;
                        default:
                            legs[i][f] = v[i][f];
                    }
                }
                i++;
            }
            return legs;
        }
    },
    expand: function(v, r) {
        var stuff = [];
        if(Ext.isArray(v)) {
            var i=0, l=v.length, f;
            while (i<l) {
                stuff[i] = {};
                for(f in v[i]){
                    stuff[i][f] = v[i][f];
                }
                i++;
            }
            return stuff;
        }
    },
    getStore: function(type){
        // XXX: this store and any other within all SABS projects
        // should use common record definitions
        // TODO: extract record definitions
        var store;
        if(type == 'basket' || type == 'landing' ){
            store = new Ext.data.JsonStore({
                //data: { results:[] },
                root: 'results',
                //lastOptions: {params:{ start:0, limit:5 }},
                //sortInfo: {field:'ADTPrice', direction:'ASC'},
                fields: SABSFactory.getRecord(type)
            });
        } else {
            store = new Ext.ux.data.JsonPagingStore({
                data: { results:[] },
                root: 'results',
                lastOptions: {params:{ start:0, limit:5 }},
                sortInfo: {field:'Price', direction:'ASC'},
                fields: SABSFactory.getRecord(type)
            });
        }
        // to make debugging easier
        Ext.StoreMgr.add(type, store);
        return store;
    },
	 prepareData: function(d, i, r) {
	 	 if ( typeof d.LegDetails !== 'undefined' ) {
            d.LegsOut = d.LegsIn = d.LegDetails.length/2;
        }

        // Stupidly, taxis and car hire use the field name "CurrencyCode"
        // rather than "Currency" in their results.  Let's remap it.
        if ( d.CurrencyCode ) {
            d.Currency = d.CurrencyCode;
            delete( d.CurrencyCode );
        }
        if (!d.Currency){
            var curr;
            if(d.DepPointOut) {
                curr = SABS.COUNTRY_TO_CURRENCY[ SABS.AIRPORT_TO_COUNTRY[ d.DepPointOut ] ];
            }
            d.Currency = curr ? curr : 'GBP';
			if (r){
			r.json.Currency = curr ? curr : 'GBP';
			}
        }

        return d;
    },
    getPanel: function(type, subtype){
	var bookingMgr;
        var store = SABSFactory.getStore(type);
        if (type == 'landing'){
            return new Ext.Panel({
                frame:false,
                //width: 800,
                minHeight: 200,
                autoHeight:true,
                layout:'fit',
                header: false,
                items: [{
                    title: 'Contact details entered',
                    autoHeight:true,
                    bodyStyle:"padding:5px",
                    html: 'cdetails'
                },
                    new Ext.DataView({
                        store: store,
                        tpl: SABSFactory.getTemplate(type),
                        autoHeight:true,
                        minHeight: 200,
                        singleSelect: true,
                        selectedClass: '',
                        itemSelector:'div.product-wrap',
                        emptyText: subtype === 'booking'? '' : 'No results to display',
                        prepareData: this.prepareData
                    }),
                {
                    title: 'Enquiry reference',
                    autoHeight:true,
                    bodyStyle:"padding:5px",
                    html: 'ref'
                }],
                getStore: function(){
                    return this.items.get(1).store;
                },
                setContactDetails: function(str){
                    this.items.get(0).body.update(str);
                },
                setEnquiryReference: function(str){
                    this.items.get(2).body.update(str);
                }
            });
        }
        else if(type == 'basket'){
			
	    var button;
		if (subtype == 'booking'){
				
		var bookBtn = new Ext.Toolbar.Button({
            text: 'Book',
            toggledText: 'Stop Booking',
            // ^^^ This isn't a real property but it keeps the button
            // text in one location.
            id: 'basket-book-btn',
            disabled:false,
            enableToggle:true
            });
	    bookBtn.on('toggle', function(btn, pressed){
            if(pressed){
                btn.setText(btn.toggledText);
            } else {
                btn.setText(btn.initialConfig.text);
            }
            });	
			
       button = [bookBtn];
       
       } else {
       
       button = ['Make an Enquiry'];
       
       }
			
            return new Ext.Panel({
                frame:false,
                //width: 800,
                minHeight: 200,
                autoHeight:true,
                layout:'fit',
                header: false,
                items: new Ext.DataView({
                    store: store,
                    tpl: SABSFactory.getTemplate(type, undefined , subtype),
                    autoHeight:true,
		    bodyStyle:"padding:50px;clear: all;",
                    minHeight: 200,
                    singleSelect: true,
                    selectedClass: '',
                    itemSelector:'div.product-wrap',
                    emptyText: 'Basket is empty',
                    prepareData: this.prepareData
                }),
                getStore: function(){
                    return this.items.get(0).store;
                },
                getSelected: function(){
                    return this.items.get(0).getSelectedRecords();
                },
                initComponent: function(){
                    Ext.Panel.prototype.initComponent.call(this);
                    this.relayEvents(this.items.get(0), ['click']);
                },
				buttonAlign: 'right',
				buttons: button
               
            });
			
        }

        return new Ext.Panel({
            name:type,
            frame:false,
            //width: 800,
            minHeight: 200,
            autoHeight:true,
            layout:'fit',
            header: false,
            hidden: true,
            items: new Ext.DataView({
                store: store,
                tpl: SABSFactory.getTemplate(type),
                autoHeight:true,
                minHeight: 200,
                singleSelect: true,
                selectedClass: '',
                itemSelector:'div.product-wrap',
                emptyText: 'No results to display',
                prepareData: this.prepareData 
            }),
            bbar: new Ext.PagingToolbar({
               pageSize: 5,
               store: store,
               displayInfo: true,
               displayMsg: 'Results {0} - {1} of {2}',
               emptyMsg: "No results to display"
            }),
            //buttons: ['Add to Basket'],
            getStore: function(){
                return this.items.get(0).store;
            },
            getSelected: function(){
                return this.items.get(0).getSelectedRecords();
            },
            initComponent: function(){
                Ext.Panel.prototype.initComponent.call(this);
                this.relayEvents(this.items.get(0), ['click' ]);
            }
        });
    },
    getNoResultsHTML: function(){
        return [
            '<p></p>',
            '<div class="box">',
            '<h1>No results found...</h1>',
            '<p>Sorry, no results have been found.</p>',

            '<p>Please try amending your search options or calling us on the phone number ',
            'provided on this website, as often there can be availability from some ',
            'operators that will not show in searches, especially with last minute deals.</p>',

            '<p><a href="#" onclick="javascript:history.back(-2)">Return to the search form.</a></p>',
            '</div>'
        ].join('');
    },
    getLoadingHTML: function(){
        return [
            '<div style="text-align: center; padding: 150px">',
            '<p>Searching...</p>',
            '<img src="http://images.sabsagent.com/images/sabs2/loading-large.gif" height="32" width="32" alt="" />',
            '</div>'
        ].join('');
    },
    // WORKERS
    getCallWorker: function(cfg){
        var worker = new CallWorker(cfg);
//        worker.extraParams = { want_brochures: '1' };
        return worker;
    },
    getPollWorker: function(cfg){
        cfg.delay = 3000;
        cfg.repeat = 10;
        var worker = new SerialPollWorker(cfg);
//        worker.extraParams = { want_brochures: '1' };
        return worker;
    },
    externalFormValsFormatter: function(formVals, searchType){
    	    if(searchType === 'flight'){    
                var nights = formVals.nights.split(',');
                return {
    	            Adults:formVals.pax,
    	    	    Children:formVals.childs,
    	    	    Infants:formVals.infants,
    	    	    FlightType: 'R',
    	    	    dateFlexible:'',
    	    	    startDate: Date.parseDate(formVals.date_month + formVals.date_day, "ymd" ).format('d/m/y'),
    	    	    //endDate:
    	    	    NightsMin: nights[0],
                    NightsMax: nights[1],
                    Within: formVals.within || 0,
    	    	    startPoint: formVals.from_1,
    	    	    endPoint:  formVals.country_1,
    	    	    gateway:'',
    	    	    seatClass:'',
    	    	    type:''
    	        };    
           }
    },
    getSearchParamsFormatter: function(){
        return function(ro, searchType){  //ro set to the values filled in on the form, searchType is the type of search - flight accommodation etc
             var theRequestType;
             switch(searchType){
                case 'flight':
                    theRequestType = 'CFM';
                    break;
                case 'accommodation':
                    theRequestType = 'CAO';
                    break;
                case 'holiday':
                    theRequestType = 'CHO';
                    break;
                case 'transfer':
                    theRequestType = 'CTX';
                    break;
                case 'carhire':
                    theRequestType = 'CCH';
                    break;
             }

            //set the defaults for searches
            var def = {
                "Format":"request",
                "RequestType":theRequestType,
                "Adults": ro.Adults,
                "Children": ro.Children,
                "Infants": ro.Infants,
                "Dep1":"",
                "Dep2":"",
                "Dep3":"",
                "Dest":"",
                "dests":[],
                "SABSResortCode":"",
                "DepDateOut":"",
                "NightsMin":"",
                "NightsMax":"",
                "Rating":"",
                "Operator1":"",
                "Operator2":"",
                "Operator3":"",
                "Operator4":"",
                "SrchType":"C",
                "FlightType":"",
                "ArrTimeOut":"",
                "DepTimeIn":"",
                "DepDateIn":"",
                "Within":"",
                /*
                "RoomOcc":[{"Adults":1,"Children":0,"Infants":0}],
                */
                "tourops":[],
                "Number":"",
                "MaxPrice":"",
                "MinPrice":"",
                "ArrDateIn":"",
                "FlightNumOut":"",
                "ArrPointIn":"",
                "TravelCode":"",
                "DiscountID":"",
                "DepTimeOut":"",
                "ArrTimeIn":"",
                "DiscountGRP":"",
                "DiscountCHD":"",
                "DiscountBKG":"",
                "DiscountRule":"",
                "FlightNumIn":"",
                "DiscountADT":"",
                "FlightTime":"",
                "deps":[],
                "TouropIns":"N",
                "RecType":"JNY",
                "MaxRecs":300,
                "InsCompany":"TBA",
                "StartRec":0,
                "RecAge":0
            };

            // Convert the form date values into sabs YYMMDD
            if ( typeof ro.endDate !== 'undefined' ) {
                ro.endDate = ro.endDate.split('/').reverse().join('');
            }
            if ( typeof ro.startDate !== 'undefined' ) {
                ro.startDate = ro.startDate.split('/').reverse().join('');
            }
            // If there's both a start and end date then figure out the
            // number of nights 
            var nights;
            if ( typeof ro.endDate !== 'undefined' &&
                 typeof ro.startDate !== 'undefined' )
            {
                var startDate = Date.parseDate(ro.startDate, 'ymd');
				var endDate;
				if (Date.parseDate(ro.endDate, 'ymd')){
                endDate = Date.parseDate(ro.endDate, 'ymd');
				}else {
				endDate = Date.parseDate(ro.endDate, 'd/m/y');
				}
                nights = startDate.getElapsed(endDate)/MSECS_IN_DAY;
                nights = parseInt(Math.round(nights), 10);
                
                
            }

            if ( typeof ro.startTime !== 'undefined' ) {
                ro.startTime = ro.startTime.split(':').join('');
            }
            if ( typeof ro.endTime !== 'undefined' ) {
                ro.endTime = ro.endTime.split(':').join('');
            }

            switch (searchType) {
                case 'accommodation':
                    var data = Ext.apply(def, SABSFactory.getMultipleRoomDetails(ro) );

                    return Ext.apply(data, {
                        Dest: ro.gateway ? ro.gateway : ro.resortcode,
                        SABSResortCode: ro.resortcode,
                        // TODO
                        Rating: "",
                        DepDateOut: ro.startDate,
				//		DepDateIn: ro.endDate,
				//		ArrDateIn: ro.endDate,
                        NightsMin: nights,
                        NightsMax: nights,
                        BoardBasis: ro.BoardBasis
                    });
                case 'transfer':
                    var returnorsingle = ro.returnorsingle || '';
                    return Ext.apply(def, {
                        Dep1: ro.startPoint,        // UK Departure Airport
                        Dest: ro.gateway ? ro.gateway : ro.resortcode,
                        SABSResortCode: ro.resortcode,
                        NewResortCode: ro.resortcode,
                        DepDateOut: ro.startDate,
                        DepDateIn: returnorsingle === 'on' ? ro.endDate : '',                 
                        ArrTimeOut: ro.startTime,
                        DepTimeIn: ro.endTime,
                        NightsMin: '',
                        NightsMax: '',
			FlightType: returnorsingle === 'on' ? "R" : "O"
                    });
                case 'carhire':
                    return Ext.apply(def, {
                        Dest: ro.gateway,
                        SABSResortCode: ro.resortcode,
                        DepDateOut: ro.startDate,
                        ArrTimeOut: ro.startTime,
						DepTimeOut: ro.startTime,
						DepDateIn: ro.endDate,
                        DepTimeIn: ro.endTime,
						ArrTimeIn: ro.endTime,
                        NightsMin: nights,
                        NightsMax: nights,
						Nights: nights
                    });
                case 'holiday':
                    return Ext.apply(def, {
                        Dep1: ro.startPoint,
                        //Dest: ro.gateway,
                        Dest: ro.type==='G' ? '*'+ ro.endPoint: ro.endPoint,
                        DepDateOut: ro.startDate,
                        NightsMin: nights,
                        NightsMax: nights,
                        Within: ro.datesFlexible ? '3' : '',
                        BoardBasis: ro.BoardBasis,
                        Rating: ro.Rating
                    });
                case 'flight':
                    return Ext.apply(def, {
                        Rating: ro.seatClass,
                        FlightType: ro.FlightType,
                        DirectFlights: ro.DirectFlights ? 'Y' : 'N',
                        Dep1: ro.startPoint,
                        //Dest: ro.gateway,
                        Dest: ro.type==='G' ? '*'+ ro.endPoint: ro.endPoint,
                        DepDateOut: ro.startDate,
                        NightsMin: ro.NightsMin || nights,
                        NightsMax: ro.NightsMax || nights,
                        Within: ro.datesFlexible ? '3' : ''
                    });
            }
        };
    },
    getMultipleRoomDetails: function(ro) {
        var rooms = 0;
        var totalAdults = 0;
        var totalChildren = 0;
        var roomOcc = [];
        while ( ro.room_occupancy.length ) {
            var adults = parseInt( ro.room_occupancy.shift(), 10 ) || 0;
            var children = parseInt( ro.room_occupancy.shift(), 10 ) || 0;
            totalAdults += adults;
            totalChildren += children;

            roomOcc.push({
                Adults: adults,
                Children: children,
                Infants: 0
            });
        }

        return {
            RoomOcc: roomOcc,
            Adults: totalAdults,
            Children: totalChildren,
            Infants: 0
        };
    },
    getContactDetailsFormatter: function(){
        var formatPhoneForStoring = function(phone){
            phone = phone.replace(/\s+/g,'');
            phone = phone.replace(/\+/g,'0');
            var pa=[];
            var numstart = phone.length-12;
            pa[2] = String(phone.substring(numstart));
            var acodestart = (numstart - 3) || 0;
            pa[1] = String(phone.substring(acodestart, numstart-1));
            pa[0] = String(phone.substring(0, acodestart-1));
            return pa;
        };
        return function(data){
            var json = [];
            if(data.Title && data.Forename && data.Surname) {
                //console.log('got title, forename and surname');
                json.push({ //NME
                    RecType: 'NME',
                    Title: data.Title,
                    Forename: data.Forename,
                    Surname: data.Surname,
                    PersonAgeType: 'A'
                });
            }
            if(data.Address) {
                json.push({ //ADR
                    RecType: 'ADR',
                    AddrType: 'Addr1',
                    House: data.House,
                    Address: data.Address.replace(/(\r\n)|\r|\n/g, "|"),
                    County: data.County,
                    PostCode: data.PostCode
                });
            }
            if(data.Email) {
                json.push({ //ADR-Email
                    RecType: 'ADR',
                    AddrType: 'Email',
                    Address: data.Email
                });
            }
            if(data.Phone){// && phone[0] && phone[1] && phone[2]) {
                var phone = formatPhoneForStoring(data.Phone);
                json.push({ //PHN
                    RecType: 'PHN',
                    PhoneType: 'H',
                    /* relaxed limitations */
                    CountryCode: phone[0],
                    AreaCode: phone[1],
                    'Number': phone[2],
                    Extension: ''//data.PhoneExt
                });
            }
            if(data.Mobile){// && mobile[0] && mobile[1] && mobile[2]) {
                var mobile = formatPhoneForStoring(data.Mobile);
                json.push({ //PHN
                    RecType: 'PHN',
                    PhoneType: 'M',
                    /* relaxed limitations  */
                    CountryCode: mobile[0],
                    AreaCode: mobile[1],
                    'Number': mobile[2],
                    Extension: ''//data.MobileExt
                });
            }
            if(data.ContactTime) {
                json.push({ //NTE-ContactTime
                    RecType: 'NTE',
                    Title: 'ContactTime',
                    Content: data.ContactTime
                });
            }
            if(data.Comments) {
                json.push({ //NTE-Comment
                    RecType: 'NTE',
                    Title: 'Comments',
                    Content: data.Comments.replace(/(\r\n)|\r|\n/g, "|")
                });
            }
            return json;
        };
    },
    // PAGE ACTIONS
    getPageAction: function(cfg){
	    SABSFactory.IsFromOld = cfg.consumer === 'old' ? true : false;
            if(cfg.stage == 'externalform'){ 
	        return function(){
                
	        Ext.Ajax.request({
                    url: '/cgi-bin/SAPS/getSession.pl',
                    success: function(){
		        var sessid = SessionDataProvider.getSession();
		        if (!SessionDataProvider.hasCookie('booking')){
		           SessionDataProvider.createCookie('booking', sessid+'-book');
		        }
		        if (!SessionDataProvider.hasCookie('basket')){
		           SessionDataProvider.createCookie('basket', sessid+'-bask');
		        }
                        SessionDataProvider.createCookie('search_saps', sessid);
                        var formVals = SABSFactory.externalFormValsFormatter(cfg.params, cfg.type);	
		        var ro = SABSFactory.getSearchParamsFormatter()(formVals,cfg.type); //form values sent into the SearchParamsFormatter for formatting
                        SessionDataProvider.getSession(
		        function(session){
		            SABSFactory.getCallWorker({
                                session: session,
                                SABSConfig:SABS.Config, 
                                searchType:cfg.type,
                                url: '/cgi-bin/SAPS/JSONCall.pl',
                                searchParams: ro,
                                listeners: { 
                                     'start': function(){
                                     },
                                     'complete': function(){ 
                                        SessionDataProvider.storeSearchObject(ro, function(){
                                            location.href = cfg.next;
                                        });
                                    },
                                    'error': function(worker, type, msg){
                                        Ext.Msg.alert('Error', type+':<br/>'+msg);
                                    }
                                }
                            }).start();
                        }); 
                    },
                    scope: this
                });
		    	
                };
	} else if(cfg.stage == 'form'){
            return function(){
            /* get the 'renderTO property of the cfg object that is passed as a param to this method. Find the dom elem with this id */ 
               
			Ext.Ajax.request({
            url: '/cgi-bin/SAPS/getSession.pl',
            success: function(){
			
				var sessid = SessionDataProvider.getSession();

				if (!SessionDataProvider.hasCookie('booking')){
				   SessionDataProvider.createCookie('booking', sessid+'-book');
				}
				
				if (!SessionDataProvider.hasCookie('basket')){
				   SessionDataProvider.createCookie('basket', sessid+'-bask');
				}
				
			   var ct = Ext.get(cfg.renderTo); 
               var f = SABSFactory.getForm(cfg.type, ct.getWidth(true));
                f.render(ct);
                f.buttons[1].on('click', function(btn){
                    var f = btn.ownerCt.getForm();
                    if(f.isValid()){
						var sessid = SessionDataProvider.getSession();
						SessionDataProvider.createCookie('search_saps', sessid);
                        
						var formVals = f.getValues();
                        var ro = SABSFactory.getSearchParamsFormatter()(formVals,cfg.type); //form values sent into the SearchParamsFormatter for formatting
                        SessionDataProvider.getSession(
						function(session){
								SABSFactory.getCallWorker({
                                session: session,
                               SABSConfig:SABS.Config, 
                                searchType:cfg.type,
                                url: '/cgi-bin/SAPS/JSONCall.pl',
                                searchParams: ro,
                                listeners: {
                                    'start': function(){
                                        ct.mask("Searching...");
                                    },
                                    'complete': function(){
										SessionDataProvider.storeSearchObject(ro, function(){
                                            location.href = cfg.next;
                                        });
                                    },
                                    'error': function(worker, type, msg){
                                        ct.unmask();
                                        Ext.Msg.alert('Error', type+':<br/>'+msg);
                                    }
                                }
                            }).start();
                       
						}); 
                    }
                }); 		
			},
            scope: this
            });
			
            };
        } else if(cfg.stage == 'results'){
            return function(){
                if(SessionDataProvider.hasSession()){
			var sessid = SessionDataProvider.getSession();
					
			//clear old booking cache if has one
			if (SessionDataProvider.hasCookie('booking')){
			    SessionDataProvider.retrieveBookingBasketContents(function(response){
			        var r = Ext.decode(response.responseText);
			        var recsToRemove = [];
			        Ext.each(r, function(o){
			            if (o.RecType === 'NTE' && o.Title === 'BookingStage' || o.RecType === 'NTE' && o.Title === 'BookingStatus' || o.RecType === 'NTE' && o.Title === 'BookingComplete'){
			                recsToRemove.push(o);
			            }
			        });
			        if (recsToRemove.length > 0 ){
			            SessionDataProvider.deleteFromBookingBasket(recsToRemove, function(){});
			        }
			    });
			}
                    
			var ct = Ext.get(cfg.renderTo);
                        var p = SABSFactory.getPanel(cfg.type);
                        p.on('click', function(dv, ix, node, e){
                        e.stopEvent();
                        var s = p.getStore().getAt(ix);
                        
                        if( e.target.id === 'basket' ){ 
			    if (!SessionDataProvider.hasCookie('basket')){
			        SessionDataProvider.createCookie('basket', sessid+'-bask');
			    }
							
                            if(s){
                                s = s.json;
                                try {
                                    var content = Ext.get('content_container');
                                    if ( content ) {
                                        content.mask('Adding to Basket...');
                                        content.unmask.defer(2000, content);
                                    }
                                    SessionDataProvider.addToBasket([s], function(){
                                        SABSFactory.UpdateBasketSummary();
                                    });
                                } catch(er){
                                    Ext.Msg.alert('Error', er);
                                }
                            }
                        } else if( e.target.id === 'book' ){

			    if (!SessionDataProvider.hasCookie('booking')){	
			        SessionDataProvider.createCookie('booking', sessid+'-book');
                            }
							
			    if(s){
                                s = s.json;
                                 try {
                                    var content = Ext.get('content_container');
                                    if ( content ) {
                                        content.mask('Starting Booking Process...');
                                        content.unmask.defer(2000, content);
                                    }
                                                         
				    SessionDataProvider.addToBookingBasket([s], function(){});
				    SessionDataProvider.retrieveBookingBasketContents(function(response){
				        var r = Ext.decode(response.responseText);
				        var recsToRemove = [];        
				        Ext.each(r, function(o){
				        if (o.RecType != 'SYS' && o.RecType != 'NTE' ){
				        recsToRemove.push(o);
				        }
				        });
				        SessionDataProvider.deleteFromBookingBasket(recsToRemove, function(){
				            SessionDataProvider.addToBookingBasket([s], function(){
				                document.location = SABSFactory.IsFromOld ? '/cgi-bin/newconsumerswitch.pl?consumer=new_booking&run=search_form' : '/index.php?search_stage=booking';
				            });
				        });
				    });
                                    
                                } catch(er){
                                    Ext.Msg.alert('Error', er);
                                }
                            }
                        } else if( e.target.id === 'brochure' ){
                            var s = p.getStore().getAt(ix);
                            if(s){
                                BrochureWindow.showBrochure(s.json);
                            }
                        }
                    });
                    //var items = [];
                    SABSFactory.getPollWorker({
                        offset: 0,
                        delay: 2000,
                        url: '/cgi-bin/SAPS/JsponPollwk.pl',
                        session: SessionDataProvider.getCookie('search_saps'),
                        searchType:cfg.type,
			            SABSConfig:SABS.Config, //productToApiType
                        searchDate: SessionDataProvider.getDate(),
                        listeners: {
                            'start': function(){
                                ct.dom.innerHTML = SABSFactory.getLoadingHTML();
                            },
                            'results': function(worker, type, results){
                                var st = p.getStore();
                                var filtered = SABSFactory.filterUnknownRecords(results);
                               
                                //TRS records are not returned with Date Data, so this is retrived from search cookie
                                if (p.name && p.name === 'carhire' || p.name === 'transfer' ){
                                   var params = Ext.decode(SessionDataProvider.getCookie('mySAPSPARAMS'));
                                   Ext.each(filtered, function(o){
                                       o.DepDateOut = params.DepDateOut;
                                       o.DepDateIn = params.DepDateIn;
                                   });
                                }
                                
                                if ( results.length > 0 ) {
                                    st.loadData({results:filtered}, true);
                                    st.load({params:{start:0,limit:5}});
				    st.sort('Price','ASC');
                                }

                                // Show results if we've received any data
                                if ( st.totalLength > 0 && p.hidden) {
                                    ct.dom.innerHTML = "";
                                    p.show();
                                    p.render(ct);
                                }
                            },
                            'complete': function(){
                                var st = p.getStore();
                                if ( st.totalLength === 0 ) {
                                    ct.dom.innerHTML = SABSFactory.getNoResultsHTML();
                                }
                                else if (p.hidden) {
                                    ct.dom.innerHTML = "";
                                    p.show();
                                    p.render(ct);
                                }
                            },
                            'error': function(worker,type, msg){
                                ct.dom.innerHTML = SABSFactory.getNoResultsHTML(type);
                                //Ext.Msg.alert('Error', type+':<br/>'+msg);
                            }
                        }
                    }).start();
                } else {
                    Ext.Msg.alert('Error', 'no session!');
                    //console.error('no session!');
                }
            };
        } else if (cfg.stage == 'landing'){
            return function(){
                if(SessionDataProvider.hasSession()){
                    var sessid = SessionDataProvider.getSession();
                    var ct=Ext.get(cfg.renderTo);
                    var p = SABSFactory.getPanel('landing');
                    p.render(ct);
                    try {
                        SessionDataProvider.retrieveBasketContents(function(response){
                            var r = Ext.decode(response.responseText);
                           var recs = SABSFactory.filterUnknownRecords(r);
                            p.getStore().loadData({results:recs});

                            // TODO same as the block above - abstract away
                            var nmes = [];
                            var phns = [];
                            var adrs = [];
                            var ntes = [];
                            Ext.each(r, function(o){
                                if(o.RecType == 'NME'){
                                    nmes.push(o);
                                } else if(o.RecType == 'PHN'){ 
                                    phns.push(o);
                                } else if(o.RecType == 'ADR'){ 
                                    adrs.push(o);
                                } else if(o.RecType == 'NTE'&& (o.Title == 'ContactTime'||o.Title == 'Comments') ){ 
                                    ntes.push(o);
                                }
                            });
                            var lead = nmes[0];
                            var cdetailsStr ="<ul>";
                            cdetailsStr +="<li> Name: " + lead.Title + " " + lead.Forename + " " + lead.Surname + "</li>";
                            lead = adrs[0];
                            if(lead){
                                cdetailsStr += "<li>Address: " + lead.Address + " " + lead.County +" "+ lead.PostCode+ "</li >";
                            }
                            lead = phns[0];
                            if(lead){ 
                                cdetailsStr += "<li>Telephone:" + lead.Number+ "</li> " ;
                            }
                            lead = phns[1];
                            if(lead){ 
                                cdetailsStr += "<li>Mobile:" + lead.Number+ "</li> " ;
                            }    
                            lead = adrs[1];
                            if(lead){ 
                                cdetailsStr += "<li>Email: " + lead.Address+  "</li >";
                                }
                            lead = ntes[1];
                            if(lead){ 
                                cdetailsStr += "<li>Comments: " + lead.Content+  "</li >";
                            }
                            p.setContactDetails(cdetailsStr);

                            p.setEnquiryReference(sessid);
                             ct.unmask();
                            /*  forget about that transaction now  */
                            SessionDataProvider.clearSession();
                        });
                        ct.mask("Loading basket contents...");
                    } catch(e){
                        Ext.Msg.alert('Error', e);
                    }
                    //p.buttons[0].on('click', function(){
                        //location.href = cfg.next;
                    //});
                } else {
                    SessionDataProvider.getSession();
                    //Ext.Msg.alert('Error', 'no session!');
                    //console.error('no session!');
                }
            };
        } else if (cfg.stage == 'basket'){
            return function(){
                if(SessionDataProvider.hasSession()){
                    var ct=Ext.get(cfg.renderTo);
                    var p = SABSFactory.getPanel('basket');
                    p.render(ct);
                    p.on('click', function(dv, ix, node, e){
                        //console.log('click fired', dv, ix, node, e);
                        e.stopEvent();
                        if( e.target.id === 'basket' ){
                            var store = p.getStore();
                            var s = store.getAt(ix);
                            if(s){
                                var sjson = s.json;
                                //console.log(s);
                                try {
                                        SessionDataProvider.deleteFromBasket([sjson], function(){
                                        store.remove(s);
                                        SABSFactory.UpdateBasketSummary();
                                    });
                                } catch(er){
                                    Ext.Msg.alert('Error', er);
                                }
                            }
                        }
                        else if( e.target.id === 'brochure' ){
                            var s = p.getStore().getAt(ix);
                            if(s){
                                BrochureWindow.showBrochure(s.json);
                            }
                        }
                    });
                    try {
			   SessionDataProvider.retrieveBasketContents(function(response){
                            var r = Ext.decode(response.responseText);
                            //console.log(r);
                            var recs = SABSFactory.filterUnknownRecords(r);
                            //TRS records are not returned with Date Data, so this is retrived from search cookie
                            
                            var params = Ext.decode(SessionDataProvider.getCookie('mySAPSPARAMS'));
                            Ext.each(recs, function(o){
                                if (o.RecType === 'TRS'){
                                    o.DepDateOut = params.DepDateOut;
                                    o.DepDateIn = params.DepDateIn;
                                }
                            });
                            
                            p.getStore().loadData({results:recs});
                            ct.unmask();
                        });
                        ct.mask("Loading basket contents...");
                    } catch(e){
                        Ext.Msg.alert('Error', e);
                    }
                    p.buttons[0].on('click', function(){
                        location.href = cfg.next;
                    });
                } else {
                    SessionDataProvider.getSession();
                    //Ext.Msg.alert('Error', 'no session!');
                    //console.error('no sessiofrn!');
                }
            };
	        } else if (cfg.stage == 'booking'){
            return function(){
                if(SessionDataProvider.hasSession()){
                    var ct=Ext.get(cfg.renderTo);
                    var p = SABSFactory.getPanel('basket', 'booking');
                    p.on('render', function(passed){
			var tbar = passed.getTopToolbar();
			var bookBtn = p.buttons[0];
			bookBtn.toggleHandler = function(btn, pressed){
			    if ( typeof bookingMgr != 'undefined'){
			        bookingMgr.stop();
			        bookingMgr.purgeListeners();
			        bookingMgr = undefined;
			    }	
			    if(pressed){
			        SABSFactory.doBooking(p);
			    }
			};
		    });
					
                    p.render(ct);
		     p.on('click', function(dv, ix, node, e){
                        //console.log('click fired', dv, ix, node, e);
                        e.stopEvent();
                        if( e.target.id === 'basket' ){
                            var store = p.getStore();
                            var s = store.getAt(ix);
                            if(s){
                                var sjson = s.json;
                                //console.log(s);
                                try {
                                    SessionDataProvider.deleteFromBasket([sjson], function(){
                                        store.remove(s);
                                        SABSFactory.UpdateBasketSummary();
                                    });
                                } catch(er){
                                    Ext.Msg.alert('Error', er);
                                }
                            }
                        
                         } else if( e.target.id === 'book-item-action'){

			     if ( typeof bookingMgr != 'undefined'){
			         var store = p.getStore();
			         var s = store.getAt(ix);
			         var bm = bookingMgr.getBookingProcessByRecord(s);
			         SABSFactory.storeContactDetails(bm);
                                 
			         s.set("Booking", "Awating Payment Confirmation");
			         this.fireEvent('checkpayment', s.id);
			         SABSFactory.buildSecpayForm(bm, s);
			     } else { 
				 var bookBtn = p.buttons[0];
				 bookBtn.setText(bookBtn.toggledText);
				 SABSFactory.doBooking(p);
			     }
						 
			  } else if( e.target.id === 'book-item-action2'){
							
			      var store = p.getStore();
			      var s = store.getAt(ix);
			      var bm = bookingMgr.getBookingProcessByRecord(s);
			      
			      if ( typeof bookingMgr != 'undefined'){
			      	 SABSFactory.buildSecpayForm(bm, s);
			      } else {
			      	  var bookBtn = p.buttons[0];
			      	  bookBtn.setText(bookBtn.toggledText);
			          SABSFactory.doBooking(p);
			      }
						 
			} else if( e.target.id === 'brochure' ){
                            var s = p.getStore().getAt(ix);
                            if(s){
                                BrochureWindow.showBrochure(s.json);
                            }
                        }
                    });
                    try {
			var div = Ext.get('basket-summary');
			div.style = 'display:hidden;';
			SessionDataProvider.retrieveBookingBasketContents(function(response){
                            var r = Ext.decode(response.responseText);
                            var recs = SABSFactory.filterUnknownRecords(r);
			    if (recs[0].RecType === 'TRS'){
                                var params = Ext.decode(SessionDataProvider.getCookie('mySAPSPARAMS'));
                                recs[0].DepDateOut = params.DepDateOut;
                                recs[0].DepDateIn = params.DepDateIn;
                            }
                            if (typeof  recs[0].Costs != 'undefined'){
			        delete recs[0].Costs;
			    }
			    if (typeof  recs[0].Errata != 'undefined'){
			        delete recs[0].Errata;
			    }
			    p.getStore().loadData({results:[recs[0]]});
                            ct.unmask();
			    if ( Ext.isIE && !Ext.isIE8 ){ 
			        p.buttons[0].focus();
			        p.buttons[0].toggle(true);
			        p.buttons[0].toggle(false);
			    }
			});
                        ct.mask("Loading basket contents...");
                    } catch(e){
                        Ext.Msg.alert('Error', e);
                    }
                    
                } else {
                    SessionDataProvider.getSession();
                    //Ext.Msg.alert('Error', 'no session!');
                    //console.error('no session!');
                }
            };
        } 
	else if (cfg.stage == 'contact'){
            return function(){
                if(SessionDataProvider.hasSession()){
                    var ct = Ext.get(cfg.renderTo);
                    var f = SABSFactory.getForm('contact');
                    f.render(ct);
                    //console.log(f.buttons);
                    f.buttons[0].on('click', function(btn){
                        var f = btn.ownerCt.getForm();
                        if(f.isValid()){
                            var data = SABSFactory.getContactDetailsFormatter()(f.getValues());
                            if(data.length){
                                try {
                                    ct.mask("Storing contact details...");
				    SessionDataProvider.retrieveBasketContents(function(response){
				        var r = Ext.decode(response.responseText);
	  			        var recs = SABSFactory.filterUnknownRecords(r);
   			                SessionDataProvider.addToBasket(data, function(){
					    SessionDataProvider.sendConfirmationEmails(function(){
					        ct.unmask();
					        SessionDataProvider.retrieveBasketContents(function(response){
					    	var r = Ext.decode(response.responseText);
					        });
					        location.href = cfg.next;
					    });
				       });
				   });            
                                } catch(e){
                                    Ext.Msg.alert('Error', e);
                                }
                            }
                        }
                    });
                } else {
                    Ext.Msg.alert('Error', 'no session!');
                    //console.error('no session!');
                }
            };
        }
    },
    UpdateBasketSummary: function() {
        SABSFactory.setBasketText();
        SABSFactory.retrieveBasketSummary();
    },
    setBasketText: function(summary) {
        var div = Ext.get('basket-summary');
        if ( !div ) {
            //console.log('Cannot find basket-summary div');
            return;
        }

        if ( div.dom.style.display != 'block' ) {
            div.dom.style.display = 'block';
        }

         if ( summary ) {
            var html;
            if ( summary.items === 0 ) {
                html = 'Enquiry basket is empty';
            } else {
		    var link = SABSFactory.IsFromOld ? 'newconsumerswitch.pl?consumer=new_basket&run=search_form&type=' : '/?search_stage=basket' ;
		    html = String.format(
		    '<a href="{0}"><span class="number">{1}</span> item{2} in enquiry basket: <span class="number">{3}</span></a>',
                    link,
                    summary.items,
                    summary.items == 1 ? '' : 's',
                    ( summary.currency == 'mixed'? 'mixed currencies' : SABS.Money( summary.price, summary.currency ))
                );
            }
            div.dom.innerHTML = html;
        }
        else {
            div.dom.innerHTML = 'Loading basket...';
        }
    },
    retrieveBasketSummary: function() {
        if ( !SessionDataProvider.hasSession() ) {
            SABSFactory.setBasketText({
                items: 0,
                price: 0,
                currency: 'GBP'
            });
        }

        try {
            SessionDataProvider.retrieveBasketContents(function(response){
                var r = Ext.decode(response.responseText);
                var types = ['HOL','JNY','FLT','ACC', 'TRS'];
                var items = 0, price = 0;
                var basketCurrency = 'GBP';
                var lastCurrency;
                Ext.each(r, function(o){
                    if(types.indexOf(o.RecType) >= 0){
                        o = SABSFactory.prepareData(o);
                        items++;
                        price += SABSFactory.getItemPrice(undefined, o);

                        // Basket currency
                        if ( !lastCurrency ) {
                            lastCurrency = o.Currency;
                            basketCurrency = o.Currency;
                        }
                        else {
                            if ( lastCurrency != o.Currency ) {
                                basketCurrency = 'mixed';
                            }
                        }
                    }
                });

                SABSFactory.setBasketText({
                    items: items,
                    price: price,
                    currency: basketCurrency
                });
            });
        } catch(er) {
            SABSFactory.setBasketText({
                items: 0,
                price: 0,
                currency: 'GBP'
            });
        }
    },
    filterUnknownRecords: function(records) {
        var filteredRecords = [];
        var types = ['HOL', 'JNY', 'FLT', 'ACC', 'TRS'];
        Ext.each(records, function(o){
            if(types.indexOf(o.RecType) >= 0){
                filteredRecords.push(o);
            }
        });

		Ext.each(records, function(o){
		    if (o.RecType === 'NTE' && o.Title === 'BookingStage'){
			var content = Ext.decode(o.Content);
			if (content.JSON){
			    filteredRecords[content.Item]  = content.JSON ;
			}
		    }
		});

		Ext.each(records, function(o){
		if (o.RecType === 'NTE' && o.Title === 'BookingComplete'){
			if (o.Content === 'Success'){
				filteredRecords[0].Booking = 'already_booked';
				filteredRecords[0].DisplayPrice = 'false';
				var button = Ext.get('basket-book-btn');
				button.setVisible( false ); 
			}
			else if (o.Content === 'Failed'){
				filteredRecords[0].Booking = 'already_booked_failed';
				var button = Ext.get('basket-book-btn');
				button.setVisible( false ); 
			
			}
				
		}		
		});
		
        return filteredRecords;
        },
	doBooking: function(pl) {
	    var p = pl;
	    var bs = p.getStore();
	    if (bs.getCount() > 0){
	    	 var recs = bs.getRange()[0];
		 var recsToBook = [];
			
		 Ext.each(recs, function(o){
		 	if (o.json.Icons.indexOf("s") >= 0){
		 		o.json.SearchParams = Ext.decode(SessionDataProvider.getParams());
		 
		 		if (o.data.RecType == 'JNY'){
		 			o.Type = 'flight';
		 			o.data.Type = 'flight';
		 	    }else if (o.data.RecType == 'FLT'){	
		 			o.Type = 'sflight';
		 			o.data.Type = 'sflight';
		 		}else if (o.data.RecType == 'HOL') {
		 			o.Type = 'holiday';
		 			o.data.Type = 'holiday';
		 		}else if (o.data.RecType == 'TRS') {
		 			if(o.data.ProductType.indexOf("Shuttle") >= 0 || o.data.ProductType.indexOf("Transfer") >= 0 || o.data.ProductType.indexOf("Taxi") >= 0){
		 			o.Type = 'transfer';
		 			o.data.Type = 'transfer';
		 			}else{
		 			o.Type = 'carhire';
		 			o.data.Type = 'carhire';
		 			}
		 		} else {
		 			o.Type = 'hotel';
		 			o.data.Type = 'hotel';
		 			o.roomType = 'ROM';
		 			o.json.Rooms = '';
		 		}
		 		recsToBook.push(o);
		 	}
		 });
		
		 _initMessageBus = function(){
		    messageBus = new Ext.util.Observable();
		    messageBus.addEvents('bookingcomplete');
		    
		    messageBus.on({	
		    	'alternatives': function(bm, bskpanel, type, alts, recId){
		    	 
		    		AltWindow.showInfo(bm, type, alts, recId);		
				    var rec = bm.store.getById(recId);
				    rec.set("Booking", "alternatives");	
		    	},
		    	'bookingcomplete': function(bm, bskpanel){
		    	}
		    });
		};
		
		_initMessageBus();
		
		bookingMgr = new ConsumerBookingManager({
		    store: bs,
		    records:recsToBook,
		    listeners: {
		    	'alternatives' : function(bm, type, alts, recId){
		    	    messageBus.fireEvent('alternatives', bm, p, type, alts, recId);
		    	},
		    	'complete' : function(bm){
		    	    messageBus.fireEvent('bookingcomplete', bm, p);
		    	}
		    	}
		});
		p.on('bookpressed', bookingMgr.doBookingStageForRecId, bookingMgr); 
		p.on('checkpayment', bookingMgr.checkPayment, bookingMgr); 
		bookingMgr.start();
	    }
	},
	buildSecpayForm: function(bm, s){
	    var merchantDetails = SessionDataProvider.getCosts() || {}; 
	    var merchant_id = merchantDetails.keys['payment.merchantid'];
	    var merchant_name = merchantDetails.keys['payment.method'];
	    var ProductToAPIType = {
	        carhire: 'BC',
                taxi: 'BT',
                hotel: 'BA',
                train: 'BR',
	    	flight: 'BF',
	    	sflight: 'BS',
	    	holiday: 'BH',
	    	transfer: 'BT'
            };
            var cfg = {
	    	amount:     SABSFactory.getItemPrice(undefined, bm.json),
	    	currency:   s.data.Currency || 'GBP',
	    	trans_id:   ProductToAPIType[bm.type] + '-' + SessionDataProvider.getCookie('booking') + '--' + SessionDataProvider.getSession(),
	    	email: 	    bm.json.Addresses[1].Address,
	    	phone: 	    bm.json.Phones[0]['Number'],
	    	address:    bm.json.Addresses[0].Address,
	    	postcode:   bm.json.Addresses[0].PostCode,
	    	time:       bm.lastResponse[0].DateStored
	    };
        
	    if (window.location.toString().indexOf("index") >= 0){
	    	cfg.callback = window.location.toString().split('/index')[0] + '/cgi-bin/SAPS/checkBookingPayment.pl';
	    } else {
	        cfg.callback = window.location.toString().split('/?search_stage')[0] + '/cgi-bin/SAPS/checkBookingPayment.pl';
	    }
	    
	    cfg.digest = this.getDigest(cfg) || '';
	    
	    if (merchant_name === 'paypal' || cfg.digest.length === 32){
	    
	        if (merchant_id){
	            cfg.merchant = merchant_id;
	        }
            
	        if (bm.json.Passengers[0].Title && bm.json.Passengers[0].Forename  && bm.json.Passengers[0].Surname){
	            cfg.firstname = bm.json.Passengers[0].Forename;
                cfg.surname = bm.json.Passengers[0].Surname;
                cfg.name = bm.json.Passengers[0].Title + ' ' + bm.json.Passengers[0].Forename  + ' ' + bm.json.Passengers[0].Surname;
	        }
	    	
	    	var url;
	    	if (merchant_name === 'realex'){
	    	    url = [
	    	        'https://epage.payandshop.com/epage.cgi?',
	    	        'MERCHANT_ID=' +  cfg.merchant,
	    	        '&ORDER_ID='   + cfg.trans_id,
	    	        '&AMOUNT=' + parseInt(Math.round( cfg.amount * 100), 10),
	    	        '&ACCOUNT=',
	    	        '&CURRENCY=' + cfg.currency,
	    	        '&TIMESTAMP=' + cfg.time,
	    	        '&MD5HASH=' + cfg.digest,
	    	        '&AUTO_SETTLE_FLAG=1'
	    	    ].join('');
	    		PaymentWindow.showInfo(url, 300, 460);
	    	}else if (merchant_name === 'paypal'){
	    		cfg.holidayTitle = bm.type + ' ' + bm.json.DepPointOutFull + ' ' + bm.json.ArrPointOutFull || '';
	    		url = ['https://www.paypal.com/cgi-bin/webscr?',
	    			'cmd=_cart',
	    			'&upload=1',
	    			'&business=' +  cfg.merchant,
	    			'&item_name_1=' + cfg.holidayTitle,
	    			'&invoice=' + cfg.trans_id,
	    			'&amount_1=' + cfg.amount,
	    			'&currency_code=' + cfg.currency,
	    			'&shipping_1=0',
	    			'&first_name=' + cfg.firstname,
	    			'&last_name=' + cfg.surname,
	    			'&email=' + cfg.email
	    		].join('');
				var mywindow = window.open(url,"paypal","menubar=1,resizable=1,width=900,height=900,scrollbars=1"); 
	    	}else{
	    	    var options = [
	           	   'dups=true,',
	               'mail_merchants=support@redskyittravel.com:bookings@ramesystravel.co.uk,',
	               'mail_attach_customer=false,',
	               'mail_attach_merchant=false,',
	               'mail_message=Thank you for booking with us<br />',
	               'IMPORTANT Your payment to Micros Travel has now been debited from your credit card. ',
	               'However your booking is not confirmed until you have received a further email giving the operators booking reference number.<br />',
	               'If this has not arrived within 24 hours please contact Micros Travel at support@redskyittravel.com or phone 0161 941 1307.,',
	               'idiompotent=true'].join('');	
	    			
	    	    url = ['https://www.secpay.com/java-bin/ValCard?',
	                'merchant=' + cfg.merchant,
	                '&trans_id=' + cfg.trans_id,
	                '&callback=' + cfg.callback,
	                '&amount=' + cfg.amount,
	                '&digest=' + cfg.digest,
	                '&currency' + cfg.currency,
	                '&customer=' + cfg.name,
	                '&ship_name=' +  cfg.name,
	                '&ship_email=' + cfg.email,
	                '&ship_addr_1=' + cfg.address,
	                '&ship_post_code=' + cfg.postcode,
	                '&ship_tel=' + cfg.phone,
	                '&order=',
	                '&branding=When+you+press+the+Authorise+button+your+booking+will+be+made.+This+may+take+a+few+moments%2C+so+please+don%27t+press+Stop+or+close+your+browser+before+you+see+the+booking+confirmation+page',
                    '&options=' + options
	            ].join('');
	    		var mywindow = window.open(url,"secpay","menubar=1,resizable=1,width=900,height=900,scrollbars=1"); 
                }
	    }else{
	    	s.set("Booking", "error-digest");
	    	var button = Ext.get('basket-book-btn');
	    	button.setVisible( false );
	    }
	},
	storeContactDetails: function(bm){
	     var recs =  [];
			
	    if (bm.json.Passengers[0].Forename && bm.json.Passengers[0].Surname){
		recs.push({ //NME
                    RecType: 'NME',
		    Title: bm.json.Passengers[0].Title,
                    Forename: bm.json.Passengers[0].Forename,
                    Surname: bm.json.Passengers[0].Surname,
                    PersonAgeType: 'A'
                });      
	    }
	    if (bm.json.Addresses[0].Address && bm.json.Addresses[0].PostCode){
	        recs.push({ //ADR
                    RecType: 'ADR',
                    AddrType: 'Addr1',
                    House: '',
                    Address: bm.json.Addresses[0].Address,
                    County: '',
                    PostCode: bm.json.Addresses[0].PostCode
                });
	    }
	    if (bm.json.Addresses[1].Address){
		recs.push({ //ADR-Email
                    RecType: 'ADR',
                    AddrType: 'Email',
                    Address: bm.json.Addresses[1].Address
                });
	    }
	    if (bm.json.Phones[0]['Number']){
		recs.push({ //PHN
                    RecType: 'PHN',
                    PhoneType: 'H',
                    CountryCode: '',
                    AreaCode: '',
                    'Number': bm.json.Phones[0]['Number'],
                    Extension: ''
                });
	    }
	    SessionDataProvider.addToBookingBasket(recs, function(){}, 'CON');
	},
	getDigest: function(cfg){
	    var id;
	    Ext.Ajax.request({
	        url: '/cgi-bin/SAPS/getMagic.pl',
	        disableCaching: false,
	        method: 'GET',
	        params: {
                    trans_id: cfg.trans_id,
		    amount: cfg.amount || ''
                },
	        async: false,
	        success: function(response, opts) {
	            var obj;
	            try {
		        obj = Ext.decode( response.responseText );
		    }
		    catch (e) {
		        options.fail.call(options.scope,
		        'Unable to decode the server response from ' +
		        ProfileAccess.PROFILE_ACCESS_URL +
		        '. The json error is: ' + e.message);
		        return;
		    }
		        id = obj.digest;
		        return;
	        }                     
	    });
	    return id;
      }
};


