var GMap2 = google.maps.Map2;
var GLatLng = google.maps.LatLng;
var GMarker = google.maps.Marker;
var GEvent = google.maps.Event;
var TripDataDS;
var TripPositionDS;
var TripPositionEG;
var CustomIconDS;
var uid;  //user id
var username;
var tid;  //trip id
var pid;  //position id
var gmarkers = [];
var zoomlevel;
var speed;
//load language file
var gt = new Gettext({ 'domain' : 'messages' });

//which unit type to show based on  selected language
//var units=gt.gettext('UnitToUse')
	if (units == "K")
      {
        var distanceDesc=gt.gettext('kilometers');
		var speedDesc='kph';
      }
      else if (units == "M")
      {
         var distanceDesc=gt.gettext('miles');
		 var speedDesc='mph';
      }
	  else if (units == "N")
      {
        var distanceDesc=gt.gettext('nautical');
		var speedDesc='nph';
      }
TrackMe = function(){};

TrackMe.prototype = {
	init:	function(){
	    if(google.maps.BrowserIsCompatible()){
			// Check user input
			this.lat	= _centerLat?_centerLat:null;
			this.lng	= _centerLng?_centerLng:null;
			this.mapType = _mapType?_mapType:'normal';
			this.zoom	= _zoom?_zoom:10;

			// Check where user is coming from by GeoIP
			if(!_centerLat || !_centerLng){
				this.lat = geoip_latitude();
				this.lng = geoip_longitude();
			}

			// if geoip failed
			if(!this.lat || !this.lng){
				this.lat = 0;
				this.lng = 0;
			}
			
			Ext.onReady(function(){
			
				// Initialize data
				var conn = new Ext.data.Connection();	
				conn.request({
					url		:	"./handler.php",
					params	:	{ mode	: "init" },
					scope	: this,
					callback:	function(o,s,r){
						if(s){
							if(r.responseText.length===0){
								Ext.Msg.alert(gt.gettext('Error'),gt.gettext('Ini Failed'));
							}else{
								var res = r.responseText;
								/* Do some initial tasks here */
								Ext.get("loading_message").remove();
								Ext.Msg.wait(gt.gettext('Loading'),gt.gettext('DataLoad'));
								setTimeout(function(){Ext.Msg.hide();}, 3000);
								this.prepare();
							}
						}
					}
				});
			},this);
		}else{
			// Something to do for Google Map imcompatible browsers
			alert(gt.gettext('ProgramFailed'));
		}	
	},
	
	prepare: function(){
		//defaults
		zoomlevel=5;
		//add refresh functions to datastore
		Ext.override(Ext.data.Store, {
			startAutoRefresh : function(interval, params, callback, refreshNow){
				if(refreshNow){
					this.load({params:params, callback:callback});
				}
				if(this.autoRefreshProcId){
					clearInterval(this.autoRefreshProcId);
				}
				this.autoRefreshProcId = setInterval(this.load.createDelegate(this, [{params:params, callback:callback}]), interval*1000);
			},
			stopAutoRefresh : function(){
				if(this.autoRefreshProcId){
					clearInterval(this.autoRefreshProcId);
				}
			}        
		}); 

		// Data Stores ************************
		UsersDataDS = new Ext.data.Store({
				  id: 'UsersDataDS',
				  proxy: new Ext.data.HttpProxy({
							url: 'handler.php',      // File to connect to
							method: 'POST'
						}),
				  baseParams:{mode: "UserList"}, // this parameter asks for listing
				  reader: new Ext.data.JsonReader({   // we tell the datastore where to get his data from
					root: 'results',
					totalProperty: 'total',
					id: 'id'
				  },[ 
					{name: 'ID', type: 'int', mapping: 'ID'},
					{name: 'username', type: 'string', mapping: 'username'}
				]),
				  sortInfo:{field: 'username', direction: "ASC"}      
				});
		TripDataDS = new Ext.data.Store({
				  id: 'TripDataDS',
				  proxy: new Ext.data.HttpProxy({
							url: 'handler.php',      // File to connect to
							method: 'POST'
						}),
				  baseParams:{mode: "TripList"}, // this parameter asks for listing
				  reader: new Ext.data.JsonReader({   // we tell the datastore where to get his data from
					root: 'results',
					totalProperty: 'total',
					id: 'id'
				  },[ 
					{name: 'ID', type: 'int', mapping: 'ID'},
					{name: 'FK_Users_ID', type: 'int', mapping: 'FK_Users_ID'},
					{name: 'Name', type: 'string', mapping: 'Name'},
					{name: 'Comments', type: 'string', mapping: 'Comments'},
					{name: 'MinDate', type: 'string', mapping: 'MinDate'},
					{name: 'MaxDate', type: 'string', mapping: 'MaxDate'}
				]),
				  sortInfo:{field: 'ID', direction: "ASC"}
			//      groupField: 'ECJOB'      
				});

		TripPositionDS = new Ext.data.Store({
				  id: 'TripPositionDS',
				  proxy: new Ext.data.HttpProxy({
							url: 'handler.php',      // File to connect to
							method: 'POST'
						}),
						baseParams:{mode: "TripPositions"}, // this parameter asks for listing
				  reader: new Ext.data.JsonReader({   // we tell the datastore where to get his data from
					root: 'results',
					totalProperty: 'total',
					id: 'id'
				  },[ 
					{name: 'TID', type: 'int', mapping: 'TID'},
					{name: 'FK_Users_ID', type: 'int', mapping: 'FK_Users_ID'},
					{name: 'TripName', type: 'string', mapping: 'TripName'},
					{name: 'ID', type: 'int', mapping: 'ID'},
					{name: 'FK_Users_ID', type: 'int', mapping: 'FK_Users_ID'},
					{name: 'FK_Trips_ID', type: 'int', mapping: 'FK_Trips_ID'},
					{name: 'FK_Icons_ID', type: 'int', mapping: 'FK_Icons_ID'},
					{name: 'Latitude', type: 'string', mapping: 'Latitude'},
					{name: 'Longitude', type: 'string', mapping: 'Longitude'},
					{name: 'Speed', type: 'float', mapping: 'Speed'},
					{name: 'Angle', type: 'float', mapping: 'Angle'},
					{name: 'DateAdded', type: 'date', mapping: 'DateAdded'},
					{name: 'DateOccurred', type: 'date', mapping: 'DateOccurred'},
					{name: 'Comments', type: 'string', mapping: 'Comments'},
					{name: 'ImageURL', type: 'string', mapping: 'ImageURL'},
					{name: 'SignalStrength', type: 'string', mapping: 'SignalStrength'},
					{name: 'SignalStrengthMax', type: 'string', mapping: 'SignalStrengthMax'},
					{name: 'SignalStrengthMin', type: 'string', mapping: 'SignalStrengthMin'},
					{name: 'BatteryStatus', type: 'float', mapping: 'BatteryStatus'},
					{name: 'IconID', type: 'string', mapping: 'IconID'},
					{name: 'IconName', type: 'string', mapping: 'IconName'},
					{name: 'IconURL', type: 'string', mapping: 'IconURL'},
					{name: 'Altitude', type: 'float', mapping: 'Altitude'}		
				]),
				  sortInfo:{field: 'DateOccurred', direction: "ASC"},
				  datachanged: function(TripPositionDS){
								console.info(TripPositionDS.getCount());
								}
				});
		AllPicturesDS = new Ext.data.Store({
				  id: 'AllPicturesDS',
				  proxy: new Ext.data.HttpProxy({
							url: 'handler.php',      // File to connect to
							method: 'POST'
						}),
						baseParams:{mode: "AllPictures"}, // this parameter asks for listing
				  reader: new Ext.data.JsonReader({   // we tell the datastore where to get his data from
					root: 'results',
					totalProperty: 'total',
					id: 'id'
				  },[ 
					{name: 'TID', type: 'int', mapping: 'TID'},
					{name: 'FK_Users_ID', type: 'int', mapping: 'FK_Users_ID'},
					{name: 'TripName', type: 'string', mapping: 'TripName'},
					{name: 'ID', type: 'int', mapping: 'ID'},
					{name: 'FK_Users_ID', type: 'int', mapping: 'FK_Users_ID'},
					{name: 'FK_Trips_ID', type: 'int', mapping: 'FK_Trips_ID'},
					{name: 'FK_Icons_ID', type: 'int', mapping: 'FK_Icons_ID'},
					{name: 'Latitude', type: 'string', mapping: 'Latitude'},
					{name: 'Longitude', type: 'string', mapping: 'Longitude'},
					{name: 'Speed', type: 'float', mapping: 'Speed'},
					{name: 'Angle', type: 'float', mapping: 'Angle'},
					{name: 'DateAdded', type: 'date', mapping: 'DateAdded'},
					{name: 'DateOccurred', type: 'date', mapping: 'DateOccurred'},
					{name: 'Comments', type: 'string', mapping: 'Comments'},
					{name: 'ImageURL', type: 'string', mapping: 'ImageURL'},
					{name: 'SignalStrength', type: 'string', mapping: 'SignalStrength'},
					{name: 'SignalStrengthMax', type: 'string', mapping: 'SignalStrengthMax'},
					{name: 'SignalStrengthMin', type: 'string', mapping: 'SignalStrengthMin'},
					{name: 'BatteryStatus', type: 'float', mapping: 'BatteryStatus'},
					{name: 'IconID', type: 'string', mapping: 'IconID'},
					{name: 'IconName', type: 'string', mapping: 'IconName'},
					{name: 'IconURL', type: 'string', mapping: 'IconURL'},
					{name: 'Altitude', type: 'float', mapping: 'Altitude'}
				]),
				  sortInfo:{field: 'DateOccurred', direction: "ASC"}
				});

		TripPicturesDS = new Ext.data.Store({
				  id: 'TripPicturesDS',
				  proxy: new Ext.data.HttpProxy({
							url: 'handler.php',      // File to connect to
							method: 'POST'
						}),
						baseParams:{mode: "TripPictures"}, // this parameter asks for listing
				  reader: new Ext.data.JsonReader({   // we tell the datastore where to get his data from
					root: 'results',
					totalProperty: 'total',
					id: 'id'
				  },[ 
					{name: 'TID', type: 'int', mapping: 'TID'},
					{name: 'FK_Users_ID', type: 'int', mapping: 'FK_Users_ID'},
					{name: 'TripName', type: 'string', mapping: 'TripName'},
					{name: 'ID', type: 'int', mapping: 'ID'},
					{name: 'FK_Users_ID', type: 'int', mapping: 'FK_Users_ID'},
					{name: 'FK_Trips_ID', type: 'int', mapping: 'FK_Trips_ID'},
					{name: 'FK_Icons_ID', type: 'int', mapping: 'FK_Icons_ID'},
					{name: 'Latitude', type: 'string', mapping: 'Latitude'},
					{name: 'Longitude', type: 'string', mapping: 'Longitude'},
					{name: 'Speed', type: 'float', mapping: 'Speed'},
					{name: 'Angle', type: 'float', mapping: 'Angle'},
					{name: 'DateAdded', type: 'date', mapping: 'DateAdded'},
					{name: 'DateOccurred', type: 'date', mapping: 'DateOccurred'},
					{name: 'Comments', type: 'string', mapping: 'Comments'},
					{name: 'ImageURL', type: 'string', mapping: 'ImageURL'},
					{name: 'SignalStrength', type: 'string', mapping: 'SignalStrength'},
					{name: 'SignalStrengthMax', type: 'string', mapping: 'SignalStrengthMax'},
					{name: 'SignalStrengthMin', type: 'string', mapping: 'SignalStrengthMin'},
					{name: 'BatteryStatus', type: 'float', mapping: 'BatteryStatus'},
					{name: 'IconID', type: 'string', mapping: 'IconID'},
					{name: 'IconName', type: 'string', mapping: 'IconName'},
					{name: 'IconURL', type: 'string', mapping: 'IconURL'},
					{name: 'Altitude', type: 'float', mapping: 'Altitude'}
				]),
				  sortInfo:{field: 'DateOccurred', direction: "ASC"}
				});

			var tplPic = new Ext.XTemplate(
				'<tpl for=".">',
					'<div class="thumb-wrap" id="{TripName}">',
					'<div class="thumb"><img src="{ImageURL}" title="{ImageURL}" width=150></div>',
					'<span class="x-editable">{Comments}</span></div>',
				'</tpl>',
				'<div class="x-clear"></div>'
			);				
			
			CustomIconDS = new Ext.data.Store({
				  id: 'CustomIconDS',
				  proxy: new Ext.data.HttpProxy({
							url: 'handler.php',      // File to connect to
							method: 'POST'
						}),
						baseParams:{mode: "GetIconList"}, // this parameter asks for listing
				  reader: new Ext.data.JsonReader({   // we tell the datastore where to get his data from
					root: 'results',
					totalProperty: 'total',
					id: 'id'
				  },[ 
					{name: 'ID', type: 'int', mapping: 'ID'},
					{name: 'Name', type: 'string', mapping: 'Name'},
					{name: 'URL', type: 'string', mapping: 'URL'}
				]),
				  sortInfo:{field: 'ID', direction: "ASC"}
				});
		// end Data Stores ************		

 //**Column Layouts for the grid
  UsersCM = new Ext.grid.ColumnModel(
    [{
        header: 'UID',
        readOnly: true,
        dataIndex: 'ID', // this is where the mapped name is important!
        width: 25,
        hidden: true
      },{
        header: 'User Name',
        dataIndex: 'username',
        width: 25,
        hidden: true
      }
	 ]);
	  
 TripPositionCM = new Ext.grid.ColumnModel(
    [{
        header: 'TID',
        readOnly: true,
        dataIndex: 'TID', // this is where the mapped name is important!
        width: 25,
        hidden: true
      },{
        header: 'FK_Users_ID',
        dataIndex: 'FK_Users_ID',
        width: 25,
        hidden: true
      },{
        header: gt.gettext('Trip Name'),
        dataIndex: 'TripName',
        width: 160,
		hidden: true
      },{
        header: gt.gettext('Position ID'),
        readOnly: true,
        dataIndex: 'ID',
        width: 65,
        hidden: false                      
      },{
        header: 'PFK_Users_ID',
        dataIndex: 'FK_Users_ID',
        width: 25,
        readOnly: true,
        hidden: true
      },{
        header: "PFK_Trips_ID",
        dataIndex: 'FK_Trips_ID',
        width: 25,
        hidden: true
     },{
        header: gt.gettext('Icon'),
        dataIndex: 'FK_Icons_ID',
        width: 75,
        hidden: false,
		editor:  new Ext.form.ComboBox({
			store: CustomIconDS,
	//		displayField:'Name',
			valueField:'ID',
			tpl: '<tpl for="."><div class="x-combo-list-item"><span style="width: 50px;"><img src="{URL}" title="{ID} | {Name}"></span></div></tpl>',
	//		tpl: '<tpl for="."><div class="x-combo-list-item"><span style="width: 50px;">{ID} </span><span style="width: 50px;">{Name}</span><span style="width: 50px;"><img src="{URL}" title="{Name}"></span></div></tpl>',
	//		<div class="thumb"><img src="{url}" title="{name}"></div>
			typeAhead:true,
			mode:'remote',
			triggerAction:'all'
		}),
		renderer:function(v,params,record){
			if (v){
				return '<img src="'+ record.data.IconURL +'">';
			}
		}
      },{
        header: gt.gettext('Latitude'),
        dataIndex: 'Latitude',
        width: 75
      },{
        header: gt.gettext('Longitude'),
        dataIndex: 'Longitude',
        width: 75
      },{
        header: gt.gettext('Speed'),
        dataIndex: 'Speed',
        width: 55
       },{
        header: gt.gettext('Angle'),
        dataIndex: 'Angle',
        width: 55
      },{
        header: gt.gettext('Altitude'),
        dataIndex: 'Altitude',
        width: 55
      },{
        header: gt.gettext('DateAdded'),
        dataIndex: 'DateAdded',
		renderer: Ext.util.Format.dateRenderer('m/d/Y h:i:s a'),
		hidden: true,
        width: 150
      },{
        header: gt.gettext('DateOccurred'),
        dataIndex: 'DateOccurred',
		renderer: Ext.util.Format.dateRenderer('m/d/Y h:i:s a'),
		hidden: false,
        width: 150
      },{
        header: gt.gettext('Comments'),
        dataIndex: 'Comments',
		locked: false,
        width: 180,
		editor: new Ext.form.TextField({ 
                        //specify options
//                        allowBlank: false //default is true (nothing entered)
                }) 
      },{
        header: gt.gettext('ImageURL'),
        dataIndex: 'ImageURL',
        width: 80
      },{
        header: gt.gettext('SignalStrength'),
        dataIndex: 'SignalStrength',
        width: 75
      },{
        header: gt.gettext('SignalStrengthMax'),
        dataIndex: 'SignalStrengthMax',
        width: 75
      },{
        header: gt.gettext('SignalStrengthMin'),
        dataIndex: 'SignalStrengthMin',
        width: 75
      },{
        header: gt.gettext('BatteryStatus'),
        dataIndex: 'BatteryStatus',
        width: 75
     },{
		header: gt.gettext('IconID'),
        dataIndex: 'IconID',
        width: 100,
        hidden: true
     },{
        header: gt.gettext('IconName'),
        dataIndex: 'IconName',
		hidden: true,
        width: 75
     },{
        header: gt.gettext('IconURL'),
        dataIndex: 'IconURL',
        width: 75,
		hidden: true,
		renderer:function(v,params,record){
					if (v){
						return '<img src="'+ v +'">';
					}
				}
     }]
    );
    TripPositionCM.defaultSortable= true;
// end Column models *****************

ImageViewer = Ext.extend(Ext.Window, {
    initComponent: function() {
        this.bodyCfg = {
            tag: 'img',
            src: this.src
        };
        ImageViewer.superclass.initComponent.apply(this, arguments);
    },

    onRender: function() {
        ImageViewer.superclass.onRender.apply(this, arguments);
        this.body.on('load', this.onImageLoad, this, {single: true});
    },

    onImageLoad: function() {
        var h = this.getFrameHeight(),
            w = this.getFrameWidth();
        this.setSize(this.body.dom.offsetWidth + w, this.body.dom.offsetHeight + h);
        if (Ext.isIE) {
            this.center();
        }
    },

    setSrc: function(src) {
        this.body.on('load', this.onImageLoad, this, {single: true});
        this.body.dom.style.width = this.body.dom.style.width = 'auto';
        this.body.dom.src = src;
    },

    initEvents: function() {
        ImageViewer.superclass.initEvents.apply(this, arguments);
        if (this.resizer) {
            this.resizer.preserveRatio = true;
        }
    }
});

// Create grid view  
var gridView = new Ext.grid.GridView({ 
   //forceFit: true, 
    getRowClass : function (row, index) { 
//	var rowid=pid;
		var cls = ''; 
		var data = row.data; 
		if (data.ID==pid) {
		cls = 'green-row';
	  }
 //     switch (data.ID) { 
 //        case 'yellow' : 
 //           cls = 'yellow-row'// highlight row yellow 
 //           break; 
 //        case 172 : 
 //           cls = 'green-row' 
 //           break; 
 //        case 'red' : 
 //           cls = 'red-row' 
 //           break;  
 //     }//end switch 
      return cls; 
   } 
});  //end gridView 

var view = new Ext.DataView({
	itemSelector: 'div.thumb-wrap',
	style:'overflow:auto',
	multiSelect: true,
//	plugins: new Ext.DataView.DragSelector({dragSafe:true}),
	store: TripPicturesDS,
	emptyText: 'No images to display',
	tpl: new Ext.XTemplate(
		'<tpl for=".">',
		'<div class="thumb-wrap" id="{ID}">',
		'<div class="thumb"><img src="{ImageURL}" class="thumb-img"></div>',
		'<span>{Comments}</span></div>',
		'</tpl>'
	),
	listeners : {
                click : {
                    fn : function( dataView, index, node, e) {
						  var record = view.getRecord(node);
						//  alert(record.get("ID"));
						imageWindow = new ImageViewer({
							title: "Date: "+record.get("DateOccurred"),
							modal:true,
							src: record.get("ImageURL"),
							hideAction: 'close'
						}).show();
					}
                }
            }

});

var allview = new Ext.DataView({
	itemSelector: 'div.thumb-wrap',
	style:'overflow:auto',
	multiSelect: true,
//	plugins: new Ext.DataView.DragSelector({dragSafe:true}),
	store: AllPicturesDS,
	emptyText: gt.gettext('No images to display'),
	tpl: new Ext.XTemplate(
		'<tpl for=".">',
		'<div class="thumb-wrap" id="{ID}">',
		'<div class="thumb"><img src="{ImageURL}" class="thumb-img"></div>',
		'<span>'+gt.gettext('Trip Name')+': {TripName}</span>',
		'<span>'+gt.gettext('Comments')+': {Comments}</span></div>',
		'</tpl>'
	),
	listeners : {
                click : {
                    fn : function( dataView, index, node, e) {
						  var record = allview.getRecord(node);
						//  alert(record.get("ID"));
						imageWindow = new ImageViewer({
							title: "Date: "+record.get("DateOccurred"),
							modal:true,
							src: record.get("ImageURL"),
							hideAction: 'close'
						}).show();
					}
                }
            }

});
// picture panes
   images = new Ext.Panel({
        id		: 'images',
        title	: gt.gettext('Trip Pictures'),
        region	: 'center',
        margins	: '5 5 5 0',
        layout	: 'fit',
        items	: view
    });

// picture panes
   allimages = new Ext.Panel({
        id			: 'allimages',
//        title:'TrackMe Pictures',
		autoScroll	: true,
        region		: 'center',
        margins		: '5 5 5 0',
        layout		: 'fit',
        items		: allview
    });	
// Editor Grids
 TripPositionEG =  new Ext.grid.EditorGridPanel({
     id: 'TripPositionEG',
     title: gt.gettext('TrackMe Position Data'),
     store: TripPositionDS,
     cm: TripPositionCM,
     loadMask: false,
//     stripeRows: true,  
//     enableColLock:false,
	trackMouseOver:true,
//	sm: new Ext.grid.RowSelectionModel({selectRow:Ext.emptyFn}),
	view: gridView,
	viewConfig: {
			forceFit:true,
			enableRowBody:true,
			showPreview:true
		},
//    autoHeight: true,
//    autoScroll: true,
     clicksToEdit:1,
     listeners:{
			cellclick : function(grid,rowIndex,colIndex,e){
				colClicked=colIndex;
				rowSelected=rowIndex;
				//grid.getView().refresh();
				//Ext.Msg.alert("Single Click",colClicked);
			},
			rowdblclick :function(grid,row,column,item){
				if (colClicked !==0){
//					Ext.Msg.alert("Double Click",colClicked);
					var record=grid.getStore().getAt(row);
					var member=record.get('ID');
					GEvent.trigger(gmarkers[member], "click");
				}
			}
	}
}); 

TripPositionEG.addListener('afteredit', handleEdit);//give event name, handler (can use 'on' shorthand for addListener)

var iconPath = 'icons/';
// Layout handling for Forms
		var nav_panel = new Ext.Panel({
			contentEl: 'tree',
			title: gt.gettext('Live Tracking'),
			iconCls:'liveicon',
			border:false			
		});
		var search_panel = new Ext.Panel({
			contentEl: 'search',
			title: gt.gettext('Search'),
			iconCls:'searchicon',
			border:false			
		});
		var weather_panel = new Ext.Panel({
			contentEl: 'weather',
			title: gt.gettext('Weather'),
			iconCls:'weathericon',
			border:false			
		});
		
		var tripselect_panel = new Ext.Panel({
			contentEl: 'tripselect',
			title: gt.gettext('Trip Select'),
			iconCls:'tripicon',
			border:false			
		});
		
		nav_panel.on('expand',function(){
			this.mode = 'navigation';
			this.searchTrackMe('LT');
		},this);
		search_panel.on('expand',function(){this.mode = 'search';},this);
		weather_panel.on('expand',function(){
			this.mode = 'weather';
			this.getWeather();
		},this);

		this.panels = [tripselect_panel,nav_panel,search_panel,weather_panel];

/* Language chooser combobox  */
    var langstore = new Ext.data.SimpleStore({
        fields: ['code', 'language', 'charset'],
        data : Ext.languagedata.languages // from languages.js
    });
    var Languagecbo = new Ext.form.ComboBox({
        store: langstore,
        displayField:'language',
        typeAhead: true,
        mode: 'local',
        triggerAction: 'all',
        emptyText:'Select a language...',
        selectOnFocus:true,
		onSelect: function(record) {
			var unitsval=units;
			window.location.search = Ext.urlEncode({"lang":record.get("code"),"charset":record.get("charset"),"units":unitsval});
		}
    });

    // set the selected language code 
    if (language) {
		// check if there's really a language with that language code
		record = langstore.data.find(function(item, key) {
			if (item.data.code==language){
			return true;
			}
			return false;
		});
		// if language was found in store assign it as current value in combobox
		if (record) {
			Languagecbo.setValue(record.data.language);
		}
    }

	/* Units chooser combobox  */
    var unitsstore = new Ext.data.SimpleStore({
        fields: ['units', 'unitsdesc'],
        data : Ext.languagedata.unitsdata // from languages.js
    });
    var Unitscbo = new Ext.form.ComboBox({
        store: unitsstore,
        displayField:'unitsdesc',
        typeAhead: true,
        mode: 'local',
        triggerAction: 'all',
        emptyText:'Select unit type...',
        selectOnFocus:true,
		onSelect: function(record) {
			window.location.search = Ext.urlEncode({"lang":language,"charset":charset,"units":record.get("units")});
		}
    });
	if (units) {
		Unitscbo.setValue(units);
		// check if there's really a language with that language code
		record = unitsstore.data.find(function(item, key) {
			if (item.data.units==units){
			return true;
			}
			return false;
		});
		// if language was found in store assign it as current value in combobox
		if (record) {
			Unitscbo.setValue(record.data.unitsdesc);
		}
	}
	
var UserListcbo = new Ext.form.ComboBox({
   id:'UserListcbo',
   fieldLabel: 'Member',
   loadingText: gt.gettext('Wait'),
   store:UsersDataDS,
   mode: 'local',
   forceselection:true,
   displayField: 'username',
   valueField: 'ID',
   anchor:'95%',
   triggerAction: 'all',
   listeners:{
			select:function(combo,record){
					uid = UserListcbo.getValue();
					username = record.data.username;
					//on user select load trip and pictures for user
					TripDataDS.load({params: {mode: 'TripList',UID: uid}});
					AllPicturesDS.load({params: {mode:'AllPictures',UID: uid}});
					}			
			}
});
     
		var viewport = new Ext.Viewport({
            layout:'border',
            items:[new Ext.Panel({   
                    region:'north',
                    //contentEl:'top_area',
                    tbar: ['<b>'+gt.gettext('User Name')+':</b>',UserListcbo,'<b> '+ gt.gettext('Language')+': ',Languagecbo,'<b> '+ gt.gettext('Units')+': ',Unitscbo],
                    margins:'5 5 5 5',  
                    height:25 
				   }),{
                    region		:'west',
                    id			:'west_region',
                    title		: gt.gettext('Control Panel'),
                    width		: 200,
					maxwidth	: 400,
                    collapsible	: true,
                    margins		:'0 0 0 5',
                    layout		:'accordion',
                    layoutConfig:{
                        animate:true
                    },
                    items: this.panels
                },
				new Ext.TabPanel({
					region	:'center',
					id		:'center_region',
					deferredRender:false,
					activeTab:0,
					items:[{
						layout	:'fit',
				//		iconCls	:'map-go',
						title	: gt.gettext('Map'),
							items	:{ contentEl:'map' }
								},{ 
						id:'trackmepics',
						title:gt.gettext('TrackMe Photo Album'),
				//		iconCls:'movie',
						closable:false,
						autoScroll:false,
						items:allimages
					}]
				}),
				SouthTab = new Ext.TabPanel({
                    region		:'south',
                    id			:'south_region',
//					titlebar:	false,
					deferredRender:false,
//                    title		:'South Region',
					collapsible	: true,
					collapsed	: true,
					split		: true, // allow resizing
					height		: 150,
					maxheight	: 300,
					margins		: '0 0 0 5'
//                    items: [TripPositionEG]
                })
             ]
        });
		

	    
	    // Search box
		var search_key = new Ext.form.TextField({
			hideLabel	:	true,
			name		:	"search_keywords",
		    id			:	"search_keywords",
		    width		:	180
		});		        

		
		var search_option = new Ext.data.SimpleStore({
			fields: ['option', 'option_title'],
			data : [
				[0,'Address'],
				[1,'Local Spots']
			]
		});
			
		var search_combo = new Ext.form.ComboBox({
			hideLabel		:	true,
		    store			: search_option,
		    displayField	:'option_title',
		    valueField		:'option',
		    value			: 0,
		    mode			: 'local',
		    triggerAction	: 'all',
		    readOnly		: true,
		    selectOnFocus	:true,
		    width			: 170,
		    listWidth		: 170
		});
				
		var search_form = new Ext.form.FormPanel({
			border: false,
			labelWidth	:	0,
			width		:	198,
			style		:	{border: "none", 'margin-top':'3px',padding:0},
			items		:	[search_key,search_combo]	
		});

		search_form.addButton({
			text	:	'Search',
			scope	:	this,
			handler	:	function(){
				var op = search_combo.getValue();
				var sk = search_key.getRawValue();
//				var tid = trip_id.getRawValue();
				if(sk.length==0){
					search_key.markInvalid("Input search keyword");
					return;
				}

				switch(op){
					case 0:
						this.searchAddress(sk);
						break;
					case 1:
						this.searchLocal(sk);
						break;					
					case 2:
						this.searchTrackMe(tid);
						break;

					default:
						break;
				}			
			}
		});
	
	    search_form.render(Ext.get('search'));	    
	    this.form = search_form;

	//TrackME Select Data From
	var TripListcbo = new Ext.form.ComboBox({
	   id				: 'TripListcbo',
	   fieldLabel		: 'ID',	
	   hideLabel		: true,
	   hiddenName		: 'cbotrip_id',
	   loadingText		: "Getting Trip List ...",
	   emptyText		: gt.gettext('Select a Trip'),
	   lazyRender		: true,
	   store			: TripDataDS,
	   mode				: 'local',
	   forceselection	: true,
	   selectOnFocus	: true,
	   editable			: true,
	   displayField		: 'Name',
	   valueField		: 'ID',
	   editable			: true,
	   anchor			: '95%',
	   triggerAction	: 'all',
			onSelect: function(record){ // override default onSelect to do redirect
				tid = record.data.ID;
				uid = record.data.FK_Users_ID;
				TripListcbo.setValue(record.data.ID);
	//			user_id.setValue(record.data.FK_Users_ID);
//				trip_name.setValue(record.data.Name);
				trip_start_date.setValue(record.data.MinDate);
				trip_end_date.setValue(record.data.MaxDate);
//				trip_id.setValue(record.data.ID);
//				tripuser_id.setValue(record.data.FK_Users_ID);
				trip_comments.setValue(record.data.Comments);
//				edit_trip_comments.setValue(record.data.Comments);
				TripListcbo.collapse();
		}
//	   listeners:{
//				select:function(field,newValue,oldValue){
//						var newValue=TripListcbo.getValue();
						//Ext.Msg.alert("select",newValue);
						//cwdfieldsDataStore.load({params: {member: newValue}});
						//MemberDescListcbo.setValue(newValue);
						//MemberPrefixListcbo.setValue(newValue);
						//reload cwfields, change desc combobox
//					}
//			}
      });

    var trip_start_date = new Ext.form.DateField({
		hideLabel	: true,
		fieldLabel	: 'Start',
        name		: 'start_date',
		anchor		: '95%',
        allowBlank	: false,
		format		: 'Y-m-d h:i:s'

    });
	
    var trip_end_date = new Ext.form.DateField({
		hideLabel	:	true,
		fieldLabel	: 'Finish',
        name		: 'end_date',
		anchor		: '95%',
        allowBlank	: false,
		format		: 'Y-m-d h:i:s'
    });
	
	var trip_comments = new Ext.form.TextArea({
		id			: 'trip_comments',
		hideLabel	: true,
		fieldLabel	: gt.gettext('Comments'),
        name		: 'trip_comments',
		anchor		: '95%',
		grow		: true,
		enabled		: false,
		growMin		: '50'
    });

	var trip_bearings = new Ext.form.Checkbox({
		id			: 'trip_bearings',
		hideLabel	: false,
		fieldLabel	: gt.gettext('Show Bearings'),
        name		: 'show_bearings',
		anchor		: '95%',
		grow		: true,
		enabled		: false,
		growMin		: '50'
    });
	
	var trip_form = new Ext.form.FormPanel({
		border		: false,
		labelWidth	: 0,
		width		: 198,
		style		: {border: "none", 'margin-top':'3px',padding:0},
		items		: [TripListcbo,trip_start_date,trip_end_date, trip_comments,trip_bearings]	
	});	    
		
		trip_form.addButton({
			text	:	gt.gettext('Edit Trip'),
			scope	:	this,
			handler	:	function(){
				tid = TripListcbo.getValue();
				uid = UserListcbo.getValue();
				tripedit(uid,tid);
			}
		});

		trip_form.addButton({
			text	:	gt.gettext('Show Trip'),
			scope	:	this,
			handler	:	function(){
				tid = TripListcbo.getValue();
				uid = UserListcbo.getValue();
				this.searchTrackMe(tid);
			}
		});
	trip_form.render(Ext.get('tripselect'));	    
	this.form = trip_form;	
// set to true or false according to the config.php settings	
if(showbearing=='yes'){
	trip_bearings.setValue(true);
} else {
	trip_bearings.setValue(false);
}
//live tracking form
	var livetrack_comments = new Ext.form.TextArea({
		id			: 'livetrack_comments',
		hideLabel	: true,
		fieldLabel	: gt.gettext('Comments'),
        name		: 'livetrack_comments',
		anchor		: '95%',
		grow		: true,
		enabled		: false,
		growMin		: '50'
    });	

zoomlevelData = [
     [1, 'Zoomlevel 0'],
    [1, 'Zoomlevel 1'],
    [2, 'Zoomlevel 2'],
    [3, 'Zoomlevel 3'],
    [4, 'Zoomlevel 4'],
    [5, 'Zoomlevel 5'],
    [6, 'Zoomlevel 6'],
    [7, 'Zoomlevel 7'],
    [8, 'Zoomlevel 8'],
    [9, 'Zoomlevel 9'],
    [10, 'Zoomlevel 10'],
    [11, 'Zoomlevel 11'],
    [12, 'Zoomlevel 12'],
    [13, 'Zoomlevel 13'],
    [14, 'Zoomlevel 14'],
    [15, 'Zoomlevel 15'],
    [16, 'Zoomlevel 16'],
    [17, 'Zoomlevel 17'],
    [18, 'Zoomlevel 18']
];

	// simple array store
	var zoomstore = new Ext.data.SimpleStore({
		fields	: ['levelid', 'desc'],
		data	: zoomlevelData
	});

	var zoomcombo = new Ext.form.ComboBox({
		id				: 'zoomcbo',
		store			: zoomstore,
		value			: zoomlevel,  //default zoom level
		valueField		: 'levelid',
		displayField	: 'desc',
		typeAhead		: true,
		mode			: 'local',
		triggerAction	: 'all',
	    anchor			: '98%',
		emptyText		: gt.gettext('Select Zoom Level'),
		selectOnFocus	:true,
		listeners:{
			select:function(field,newValule,oldValue){
					//var newZoomValue=zoomcombo.getValue();
					//Ext.Msg.alert("select",newZoomValue);
					zoomlevel=zoomcombo.getValue();
					//map.zoomTo(zoomlevel);
					map.setZoom(zoomlevel);
					//cwdfieldsDataStore.load({params: {member: newDescValue}});
					//MemberListcbo.setValue(newDescValue);
					//MemberPrefixListcbo.setValue(newDescValue);
					//reload cwfields, change desc combobox
				}
		}
	});

	var livetrack_form = new Ext.form.FormPanel({
		border		: false,
		labelWidth	: 0,
		width		: 198,
		style		: {border: "none", 'margin-top':'3px',padding:0},
		items		: [zoomcombo]	
	});	    
	
		livetrack_form.addButton({
			text	:	gt.gettext('Get Latest Position'),
			scope	:	this,
			handler	:	function(){
				TripPositionDS.load({params: {TID: tid,LiveTrack: 'yes', UID: uid}});
			}
		});
	livetrack_form.render(Ext.get('tree'));	    
	this.form = livetrack_form;	
	
TripDataDS.on('load', function() {
		TripListcbo.setValue(tid);

});

	
	    // Create Map
		var map = new GMap2(Ext.get('map').dom);
		map.enableDoubleClickZoom();
		map.enableContinuousZoom();
		map.enableScrollWheelZoom();
		map.addControl(new google.maps.LargeMapControl());
		map.addControl(new google.maps.MapTypeControl());
		map.addControl(new google.maps.ScaleControl());
		map.addControl(new google.maps.OverviewMapControl());
					map.addControl(new DragZoomControl(null,{
					buttonHTML: '<img src="./icons/zoom_in.png" style="behavior:url(./iepngfix.htc)" />',
					buttonStyle: {backgroundColor: 'white',textAlign:'center',width: '25px', border: '1px solid black', padding: '2px', position: 'absolute', top:'7px', left: '70px'},
					buttonZoomingHTML: '<img src="./icons/zoom_in.png" style="behavior:url(./iepngfix.htc)" />',
					buttonZoomingStyle: {backgroundColor: 'yellow', textAlign:'center',width: '25px', border: '1px solid black', padding: '2px', position: 'absolute', top:'7px', left: '70px'},
					backButtonEnabled: true,
					backButtonHTML: '<img src="./icons/zoom_out.png" />',
					backButtonStyle: {behavior:'url(./iepngfix.htc)', display:'none',backgroundColor: 'yellow', textAlign:'center',width: '25px', border: '1px solid black', padding: '2px', position: 'absolute', top:'7px', left: '100px'}
				}));
				

		map.setCenter(new GLatLng(this.lat,this.lng),this.zoom);
		map.setMapType(this.mapType);
		
		var obj = this;
		GEvent.addListener(map,'dragend',function(){
			if(search_key.getRawValue() && obj.mode && obj.mode=='localSearch'){
				obj.searchLocal(search_key.getRawValue());
			}else if(obj.mode && obj.mode=='weather'){
				obj.getWeather();
			}
		});

		GEvent.addListener(map,'zoomend',function(){
			if(search_key.getRawValue() && obj.mode && obj.mode=='localSearch'){
				obj.searchLocal(search_key.getRawValue());
			}else if(obj.mode && obj.mode=='weather'){
				obj.getWeather();
			}
		});
		
		this.map = map; 
		
		if(Ext.isIE){
			Ext.get('map').setStyle({height:Ext.get('center_region').getHeight()});
			map.checkResize();
			Ext.get('center_region').on('resize',function(){
				Ext.get('map').setStyle({height:Ext.get('center_region').getHeight()});
				this.map.checkResize();		
			},this);
		}			
	//load the trip combo box first time
	//load usernames
	UsersDataDS.load({params:{mode:'UserList'}});
	
	},
	
	searchAddress	:	function(opt){
		var m = this;
		var geo = new google.maps.ClientGeocoder();
		geo.getLocations(opt,function(d){
			if(d.Status.code==200 && d.Placemark){
				var pm = d.Placemark[0];

			var p = new GLatLng(pm.Point.coordinates[1],pm.Point.coordinates[0]);
				var msg = "<p>"+pm.address+"</p>";
				msg += "<p>Latitude="+p.lat()+"</p>"; 
				msg += "<p>Longitude="+p.lng()+"</p>";
				m.panAndMark({point:p,msg:msg});				
			}else{
				Ext.Msg.alert("Not Found","No location was found for "+opt);
			}
		});
		
		this.mode = 'addressSearch';
	},

	searchTrackMe	:	function(tid){
		var m = this;
//		TripDataDS.load();
		m.map.clearOverlays();
		// see if there is already a trip summary table, if there is remove it
		var tt = Ext.get('trip_summary_table');
		if(tt){ tt.remove(); }
		var trip_summary_table='<div id="trip_summary_table" class="tripsummary">' +
						 '<table><tbody>' +
						'<tr><td><img id="loading_icon" src="./images/loading.gif" /></td><td>  '+gt.gettext('Getting Trip Data')+'</td></tr><tr>' +
						'<tr><td></td><td>  '+gt.gettext('Wait')+'</td></tr><tr>' +
						 '</tr></tbody></table>' +
						 '</div>';
//		Ext.DomHelper.append('tripselect',trip_summary_table);
		//are we tracking or looking up a trip
		if (tid=='LT'){
		Ext.DomHelper.append('tree',trip_summary_table);
			TripPositionDS.load({params: {TID: tid,LiveTrack: 'yes', UID: uid}});
			TripPositionDS.startAutoRefresh(60,{TID: tid,LiveTrack: 'yes', UID: uid});			
		} else {
			TripPositionDS.stopAutoRefresh();
			Ext.DomHelper.append('tripselect',trip_summary_table);
			TripPositionDS.load({params: {TID: tid, UID: uid}});
		}
		var loadcnt=0;
		TripPositionDS.on('load',function() {
		loadcnt=loadcnt+1;
		if (loadcnt==1){ //for some reason, on load is being called multiple times,  this will only allow it to process once.
			var tc=TripPositionDS.getTotalCount();
			var loopcnt=1;
			var firstposid;

			var points=[];
			// latlng: an array of instances of GLatLng
			var latlngbounds = new GLatLngBounds( );
			//reset variables for totals
			var total_distance = 0;
			var leg_time    = 0;
			var holdtime;
			var total_time = 0;
			var display_total_time;
			var leg_distance=0;
			var otal_time;
			var holdlat;
			var holdlong;
			var holdlegtime;
			var holdspeed;
			var avg_speed;
			var speed_total;
			var photo_count = 0;
			var comment_count = 0;
			var altitude;
				TripPositionDS.each( function( item, index){	/* Loop Through each Position */
					var posID		= item.get('ID');
					var mph			= item.get('Speed') * 2.2369362920544;
					var kph			= item.get('Speed') * 3.6;
					var ft			= item.get('Altitude') * 3.2808399;
					var meters		= item.get('Altitude');
					var direction	= item.get('Angle');
					var iconid		= item.get('FK_Icons_ID');
					var iconurl		= item.get('IconURL');
					var imageurl	= item.get('ImageURL');
					//var username	= "none";
					var tripname	= item.get('TripName');
					var comments	= item.get('Comments');
					var dateoccurred=item.get('DateOccurred');
					var latitude	= item.get('Latitude');
					var longitude	= item.get('Longitude');
					if (units == "K")
					  {
						speed=kph;
						altitude	= meters;
					  }
					  else if (units == "M")
					  {
						speed=mph;
						altitude	= ft;
					  }
					  else if (units == "N")
					  {
						speed=mph;
						altitude	= ft;
					  }
					
					var distance	=0;
					var iconsize	="";
					var iconimage	="";
					var iconshadow	="";
					

					if ( comments !== "" ) {comment_count = comment_count + 1;}
					if ( imageurl !== "" ) {photo_count = photo_count + 1;}				
					 leg_time         = date('m/d/y g:i a',dateoccurred);
					 if( loopcnt==1 ){  /* Start Position */
						holdtime = dateoccurred;
						total_time = 0;
						time_since_last = 0;
						avg_speed=speed;
						speed_total=speed;
						display_total_time = gmdate("H:i:s", total_time);
						firstposid	=posID; //using this to help determine what row on the editor grid to position to
						iconsize	="medium";
						iconimage	="mapicons/start.png";
						iconshadow	="mapicons/msmarker.shadow.png";
					} else {
						leg_distance		= getdistance(latitude, longitude, holdlat, holdlong, units);
						total_distance		= total_distance+leg_distance;
						total_time			= get_elapsed_time(holdtime, dateoccurred);
						otal_time			= gmdate("H:i:s", total_time);
						time_since_last		= get_elapsed_time(holdlegtime, dateoccurred);
						speed_total			= speed_total+speed;
						avg_speed			= speed_total/loopcnt;
						if (loopcnt == tc) { /* End Position */
							iconsize	="medium";
							iconimage	="mapicons/end.png";
							iconshadow	="mapicons/msmarker.shadow.png";
						} else  {  /* All other Positions */
									if ( iconid > 0 ) {  //check for custom icon
										iconimage	=iconurl;
										iconsize	="large";
										iconshadow	="";
									} else {				
										iconsize	="small";
										iconshadow	="";
										//need to check if user wants to see direction arrows here
										var showBear=Ext.getCmp("trip_bearings").getValue();
										if (showBear==true){
											iconimage	="mapicons/arrow"+getCompassImage(direction)+".png";
										}
									}										
						}
					holdlat		= latitude;
					holdlong	= longitude;
					holdlegtime = dateoccurred;
					holdspeed	= speed;
					}
					
					var point = new GLatLng(item.get('Latitude'),item.get('Longitude'));  //location of new marker
					var marker = createMarker(point,username,tripname,leg_time,speed,avg_speed,direction,leg_distance,time_since_last,altitude,comments,iconsize,iconimage,iconshadow,imageurl,posID,firstposid);
					gmarkers[item.get('ID')] = marker;  //set the id of new marker
					m.map.addOverlay(marker);  // add marker to map
					
					latlngbounds.extend(point); //this adds all points to array so we can figure out zoom level and center of map.
					points.push(point); //build polyline
					loopcnt= loopcnt + 1;
				});
				//m.map.addOverlay(new GPolyline(points,"ff0000",5));
				m.map.addOverlay(new GPolyline(points,"blue",3));
			if (tid=='LT'){  // if we are in live tracking then get zoom level from combo box
				//if tracking more that one user will have to make sure the bound includes all user locations.
	//			var zlcombo = Ext.get('zoomcbo');
	//			var zoomlevelvalue = zoomlevel;
	//			alert ("Zoom Level Cbo: " + zoomlevel);
	//			alert ("Bounds: " + m.map.getBoundsZoomLevel( latlngbounds ));
				var checkzoom = m.map.getBoundsZoomLevel( latlngbounds ) - zoomlevel;
	//			alert ("Bounds - cboZoom: " + checkzoom);
				m.map.setCenter( latlngbounds.getCenter( ), m.map.getBoundsZoomLevel( latlngbounds )-zoomlevel);

			} else {
				//set center and zoom level based on all map points
				//alert ("LatLngBounds: " + latlngbounds);
				m.map.setCenter( latlngbounds.getCenter( ), m.map.getBoundsZoomLevel( latlngbounds ) );
				var tabcheck=SouthTab.getComponent('TripPositionEG');
				if (!tabcheck){   //if its the first time viewing a trip, expand the south region and add the position grid and images
					SouthTab.expand(); 
					SouthTab.add(TripPositionEG);
					SouthTab.setActiveTab(TripPositionEG);
				} 
				var phototabcheck=SouthTab.getComponent('images');
				if (photo_count==0) { 
					if (phototabcheck){
						SouthTab.setActiveTab(TripPositionEG);
						//hide the trip pictures tab
						SouthTab.hideTabStripItem("images");
					}
				} else {
					//refresh pictures
					TripPicturesDS.load({params: {TID: tid, UID: uid}});
					if (!phototabcheck){
						SouthTab.add(images);
					} else {
						SouthTab.unhideTabStripItem("images");
					}
				}

				}
			//update the position grid
	//		var sp = Ext.getCmp('south_region');
	//		sp.body.update('AutoID:');
			//m.viewport.getLayout().south.slideOut();

			//remove the table if it exists
			var tt = Ext.get('trip_summary_table');
			if(tt){ tt.remove(); }
			// trip summary table
			var total_map_points=loopcnt-1;
			var trip_summary_table;
			if (tid=='LT'){		//are we Live Tracking or Looking up a trip
			trip_summary_table = '<div id="trip_summary_table" class="tripsummary">' +
							 '<span class="trip_suymmary_title">'+gt.gettext('Trip Summary')+'</span>' +
							 '<table><tbody>' +
							 '<tr><td class="ts_item">'+gt.gettext('Speed')+': </td><td>'+speed.toFixed(0)+'</td></tr><tr>' +
							 '<tr><td class="ts_item">'+gt.gettext('Altitude')+': </td><td>'+total_time+'</td></tr><tr>' +
							 '<tr><td class="ts_item">'+gt.gettext('Total Distance')+': </td><td>'+total_distance.toFixed(1)+'</td></tr><tr>' +
							 '</tr></tbody></table>' +
							 '<span class="trip_suymmary_title">'+gt.gettext('Powered by')+' <a href="http://www.luisespinosa.com/trackme_eng.html" target="_blank">TrackMe</a></span>' +
							 '</div>';
			 //show trip table summary in the Live tracking Panel
			Ext.DomHelper.append('tree',trip_summary_table);
			} else {
			trip_summary_table = '<div id="trip_summary_table" class="tripsummary">' +
							 '<span class="trip_suymmary_title">'+gt.gettext('Trip Summary')+'</span>' +
							 '<table><tbody>' +
							 '<tr><td class="ts_item">'+gt.gettext('Total Distance')+': </td><td>'+total_distance.toFixed(1)+' '+distanceDesc+'</td></tr><tr>' +
							 '<tr><td class="ts_item">'+gt.gettext('Total Time')+': </td><td>'+total_time+'</td></tr><tr>' +
							 '<tr><td class="ts_item">'+gt.gettext('Total Photos')+': </td><td>'+photo_count+'</td></tr><tr>' +
							 '<tr><td class="ts_item">'+gt.gettext('Total Comments')+': </td><td>'+comment_count+'</td></tr><tr>' +
							 '<tr><td class="ts_item">'+gt.gettext('Total Points')+': </td><td>'+total_map_points+'</td></tr><tr>' +
							 '</tr></tbody></table>' +
							 '<span class="trip_suymmary_title">'+gt.gettext('Powered by')+' <a href="http://www.luisespinosa.com/trackme_eng.html" target="_blank">TrackMe</a></span>' +
							 '</div>';
			 //show trip table summary in the Trip Select Panel
			Ext.DomHelper.append('tripselect',trip_summary_table);

			 }

		}
		});
		this.mode = 'addressTrackMe';
	},
	
	searchLocal	:	function(opt){
		var m = this;
		var geo = new google.search.LocalSearch();
		geo.setCenterPoint(m.map);
		
		geo.setResultSetSize(google.search.Search.LARGE_RESULTSET);
		geo.execute(opt);
		
		if(m.grid){ m.grid.destroy(); }
		Ext.DomHelper.append('search','<img id="loading_icon" src="./images/loading.gif" />');
		
		geo.setSearchCompleteCallback(geo,function(){
			Ext.get('loading_icon').remove();
			m.map.clearOverlays();
			var res = this.results;
			
			if(res && res.length>0){

				var data = [];
				var markers = [];
				for(var i=0; i<res.length; i++){
					markers[i] = (function(pt){
						var marker = new GMarker(new GLatLng(pt.lat,pt.lng));
						GEvent.addListener(marker,'click',function(){
							marker.openInfoWindowHtml(pt.html);
						});	
						m.map.addOverlay(marker);
					
						data[i] = [pt.html.innerHTML];
						return marker;
					})(res[i]);
				}
			
				var ds = new Ext.data.Store({
					reader	:	new Ext.data.ArrayReader({},[{name: 'html'}])
				});
				ds.loadData(data);

				var sm = new Ext.grid.RowSelectionModel({singleSelect:true});
				sm.on('rowselect', function(sm,ri){
					GEvent.trigger(markers[ri],'click');
				}); 
				
				var grid = new Ext.grid.GridPanel({
					store: ds,
					columns:[
						{header: '', width: 195, dataIndex: 'html' }
					],
					width: 195,
					height:300,
					autoScroll: true,
					sm: sm
				});
				
				grid.render(Ext.get('search'));
				m.grid = grid;
			}else{
				Ext.get('loading_icon').destroy();
				Ext.Msg.alert("Not Found","No \""+opt+ "\" was found for this area");				
			}
		});
		
		this.mode = 'localSearch';		
	},
	
	panAndMark:	function(opt){
		var m = this.map;
		var p = opt.point;
		var mrk = new GMarker(p);

		m.clearOverlays();
		m.addOverlay(mrk);
		m.setCenter(p);		

		if(opt.msg){			
			mrk.openInfoWindowHtml(opt.msg);
			GEvent.addListener(mrk,'click',function(){
				this.openInfoWindow(opt.msg);
			});
		}
	},

	LiveTrack:	function(opt){
	//	TripPositionDS.load({params: {TID: tid,LiveTrack: 'yes', UID: 1}});
	//	TripPositionDS.startAutoRefresh(10);
	//	Ext.Msg.alert("Live Track","should auto refresh now");
	//	Ext.TaskMgr.start({
	//		run: TripPositionDS.reload,
	//		run: TripPositionDS.load({params: {TID: tid,LiveTrack: 'yes', UID: 1}}),
	//		scope: TripPositionDS,
	//		interval:4000
	//		//args:[{params:{start:0, limit:list_count}, add:false}]
	//	});
	/**
		var m = this.map;
		var p = opt.point;
		var mrk = new GMarker(p);

		m.clearOverlays();
		m.addOverlay(mrk);
		m.setCenter(p);		

		if(opt.msg){			
			mrk.openInfoWindowHtml(opt.msg);
			GEvent.addListener(mrk,'click',function(){
				this.openInfoWindow(opt.msg);
			});
		}
	**/
	},
	
	getWeather: function(){
		if(this.w_request && this.w_request.isLoading()){
			this.w_request.abort();
			if(Ext.get('loading_icon')){
				Ext.get('loading_icon').remove();
			}
		}

		var conn = new Ext.data.Connection();
		this.w_request = conn;
		
		var center = this.map.getCenter();
		var lat = center.lat();
		var lng = center.lng();

		var wt = Ext.get('weather_table');
		if(wt){ wt.remove(); }
		Ext.DomHelper.append('weather','<img id="loading_icon" src="./images/loading.gif" />');
				
		conn.request({
			url		:	"./handler.php",
			params	:	{ 
				mode	: "weather",
				lat	: lat, 
				lng	: lng
			},
			scope	:	this,
			callback:	function(o,s,r){
				Ext.get('loading_icon').remove();
				if(s){
					if(r.responseText.length===0){ return; }
					eval("var res = {result:"+r.responseText+"}");
					if(res.length===0){ return; }
					var result = res.result;
					var weather_table = '<div id="weather_table" class="weather">' +
						'<span class="weather_title">'+result.title+'</span>' +
						'<table><tbody>' +
						'<tr><td>Today</td><td>-></td></tr><tr>' +
						'<td class="weather_item"><img src="'+result.today.icon+'" /></td>' +
						'<td class="weather_item"><img src="'+result.tomorrow.icon+'" /></td>' +
						'</tr><tr>' +
						'<td class="weather_item"><span class="weather_hi">'+result.today.hi+'</span>' +
						'/<span class="weather_lo">'+result.today.lo+'</span></td>' +
						'<td class="weather_item"><span class="weather_hi">'+result.tomorrow.hi+'</span>' +
						'/<span class="weather_lo">'+result.tomorrow.lo+'</span></td>' +
						'</tr></tbody></table>' +
						'<span class="weather_title">Powered by <a href="http://weather.yahoo.com/" target="_blank">Yahoo Weather</a></span>' +
						'</div>';

					Ext.DomHelper.append('weather',weather_table);
				}
			}
		});
	},
	
	unload:	function(){
//		this.tree.purgeListeners();
		this.form.buttons[0].purgeListeners();
		for(var i=0; i<this.panels.length; i++){
			this.panels[i].purgeListeners();
		}
		google.maps.Unload();
		delete this;
	}
};

var mapObj = new TrackMe();

window.onload = function(){
	mapObj.init();
};

window.onunload = function(){
	mapObj.unload;
};


function createMarker(point, username, tripname, dateoccurred, speed, avg_speed, direction, distance,elapsed_time, altitude, comments, iconsize, iconimg, iconshadow, imageurl,positionID,firstposid) {
	// Create a base icon for all of our markers that specifies the
	// shadow, icon dimensions, etc.
	var icon = new GIcon(G_DEFAULT_ICON);
	icon.image = "" + iconimg + "";
	icon.shadow = "" + iconshadow + "";
	icon.iconSize = new GSize(12, 20);
	icon.shadowSize = new GSize(22, 20);
	icon.iconAnchor = new GPoint(3, 10);
	icon.infoWindowAnchor = new GPoint(5, 1);

    if (iconsize == "large") {
	    icon.iconSize = new GSize(35, 43);
	    icon.shadowSize = new GSize(35, 33);
	    icon.iconAnchor = new GPoint(6, 40);
	    icon.infoWindowAnchor = new GPoint(5, 1);
    } else if (iconsize == "medium") {
	    icon.iconSize = new GSize(25, 33);
	    icon.shadowSize = new GSize(25, 23);
	    icon.iconAnchor = new GPoint(6, 30);
	    icon.infoWindowAnchor = new GPoint(5, 1);
    } else {
	    icon.iconSize = new GSize(12, 12);
	    icon.shadowSize = new GSize(12, 10);
	    icon.iconAnchor = new GPoint(6, 20);
	    icon.infoWindowAnchor = new GPoint(5, 1);
    }
	
	if ( imageurl !== "" ) {  /* this is for the google map popup bubble */
		imageurl='<td colspan=3 align=center><a href=' + imageurl +  'target=_blank><img src=' + imageurl +  ' width=200 border=0></a></td>';
	} else {
		imageurl="   <td colspan=3 align=center></td>";
	}
	
    var marker = new GMarker(point,icon);

					// this creates the pop up bubble that displays info when a user clicks on a marker
				GEvent.addListener(marker, "click", function() {
				//TripPositionEG.getSelectionModel().selectRow(117);
				var rownumber	= positionID-firstposid;
				pid				= positionID;
				//alert ("position id: " + pid);
				//Ext.getCmp('TripPositionEG').getView().focusRow(rownumber);
					setPosOnGrid(rownumber);
					marker.openInfoWindowHtml('<table border=0 style=\"font-size:95%;font-family:arial,helvetica,sans-serif;\">' +
					'<tr>' +
					'	 <td align=left><b>'+gt.gettext('Position ID')+': </b>' + positionID +  '&nbsp;</td>' + 
					'	 <td>&nbsp;</td>' +
					'	 <td rowspan=2 align=right><img src=mapicons/compass' + getCompassImage(direction) + '.jpg alt= /></td>' +
					'</tr>' +
					'<tr>' +
					'	 <td align=left><b>'+gt.gettext('User')+': </b>' + username +  '</td>' +
					'	 <td align=right><b>'+gt.gettext('Trip')+': </b>' + tripname +  '</td>' +
					'</tr>' +
					'<tr><td colspan=3><hr></td></tr>' +
					'<tr>' +
					'	 <td align=left><b>'+gt.gettext('Time')+': </b>' + dateoccurred +  '</td>' +
					'	 <td align=right><b>'+gt.gettext('Time Traveled')+': </b>' + elapsed_time +  '</td>' +
					'	 <td>&nbsp;</td>' +
					'</tr>' +
					'<tr>' +
					'	 <td align=left><b>'+gt.gettext('Speed')+': </b>' + speed.toFixed(0) +  ' '+speedDesc+'</td>' +
					'	 <td align=right><b>'+gt.gettext('Average Speed')+': </b>' + avg_speed.toFixed(0) +  ' '+speedDesc+'</td>' +
					'	 <td>&nbsp;</td>' +
					'</tr>' +
					'<tr>' +
					'	 <td align=left><b>'+gt.gettext('Altitude')+': </b>' + altitude.toFixed(3) +  '</td>' +
					'	 <td align=right><b>'+gt.gettext('Distance')+': </b>' + distance.toFixed(3) +  '</td>' +
					'	 <td>&nbsp;</td>' +
					'</tr>' +
					'<tr>' +
					'	 <td colspan=3 align=left><b>'+gt.gettext('Comments')+': </b>' + comments + '</td>' +
					'</tr>' +
					'<tr>' + imageurl + '</tr>' +
					'<tr>' +
					'  <td colspan=3><hr></td>' +
					'</tr>' +
					'<tr>' +
					'  <td colspan=3><b><a href=http://forum.xda-developers.com/showthread.php?t=340667 target=_blank>TrackMe</a> '+gt.gettext('Created by')+' <a href=http://www.luisespinosa.com/ target=_blank>Luis Espinosa</a></td>' +
					'</tr>' +
					'</table>'
					);
				});

    return marker;
}
// this chooses the proper image for our litte compass in the popup window
function getCompassImage(azimuth) {
    if ((azimuth >= 337 && azimuth <= 360) || (azimuth >= 0 && azimuth < 23)) {
            return "0";
    } else if (azimuth >= 23 && azimuth < 68) {
            return "45";
    } else if (azimuth >= 68 && azimuth < 113) {
            return "90";
    } else if (azimuth >= 113 && azimuth < 158) {
            return "135";
    } else if (azimuth >= 158 && azimuth < 203) {
            return "180";
    } else if (azimuth >= 203 && azimuth < 248) {
            return "225";
    } else if (azimuth >= 248 && azimuth < 293) {
            return "270";
    } else if (azimuth >= 293 && azimuth < 337) {
            return "315";
	} else {
    return "";
	}
}
function calculateDistance(lat1, lon1, lat2, lon2)
{
	try
	{
		var glatlng1 = new GLatLng(lat1, lon1);
		var glatlng2 = new GLatLng(lat2, lon2);
		var miledistance = glatlng1.distanceFrom(glatlng2, 3959).toFixed(1);
		var kmdistance = (miledistance * 1.609344).toFixed(1);
		
		return miledistance;
	}
	catch (error)
	{
		alert(error);
	}
}

function toRad(deg) {
 return deg * Math.PI/180;
}

//1 Kilometer = 0.621371192237334 Miles
// Function to calculate distance between points(Haversine formula)
function getdistance(lat1, lon1, lat2, lon2, unit)  {
	if (lat1 == lat2 && lon1 == lon2) { return 0; }
		var R = 6371; // earths radius
		var dLat = toRad((lat2-lat1));
		var dLon = toRad((lon2-lon1)); 
		var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
				Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * 
				Math.sin(dLon/2) * Math.sin(dLon/2); 
		var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
		var d = R * c;
		
	  var kilometers = d;
	  
      unit = strtoupper(unit);
	  if (!lat2){
		return 0;
	  } 
	  else if (unit == "K")
      {
        return (kilometers);
      }
      else if (unit == "M")
      {
        return (kilometers / 1.609344);
      }
	  else if (unit == "N")
      {
        return (kilometers * 0.539956803);
      }
      else
      {
        return kilometers;
      }
}

//Miro ***********
function getdistance2(lat1, lon1, lat2, lon2, unit) {
	if (lat1 == lat2 && lon1 == lon2) { return 0; }
var theta, dist, theDistance;
theta = lon1 - lon2;
dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
miles = dist * 60 * 1.1515;
unit = unit.toUpperCase();

if (unit == "K") {
return (miles * 1.609344);
} else if (unit == "N") {
return (miles * 0.8684);
} else {
return miles;
}
}
//*********************


// Function to calculate time between points
function get_elapsed_time(time_start, time_end, units, decimals) {
		units = 'seconds';
		decimals = 0;
		timediff=(time_end - time_start);

		weeks = Math.floor(timediff / (1000 * 60 * 60 * 24 * 7));
		timediff -= weeks * (1000 * 60 * 60 * 24 * 7);

		days = Math.floor(timediff / (1000 * 60 * 60 * 24)); 
		timediff -= days * (1000 * 60 * 60 * 24);

		hours = Math.floor(timediff / (1000 * 60 * 60)); 
		timediff -= hours * (1000 * 60 * 60);

		mins = Math.floor(timediff / (1000 * 60)); 
		timediff -= mins * (1000 * 60);

		secs = Math.floor(timediff / 1000); 
		timediff -= secs * 1000;		
		
		if (weeks>0) {
			var elapsed_time=weeks + " "+ gt.gettext('weeks')+", " + days + " "+ gt.gettext('days')+", " + hours + " "+ gt.gettext('hours')+", " + mins + " "+ gt.gettext('minutes')+", and " + secs + " "+ gt.gettext('seconds');
		} else if (days>0) {
				var elapsed_time=days + " "+ gt.gettext('days')+", " + hours + " "+ gt.gettext('hours')+", " + mins + " "+ gt.gettext('minutes')+", and " + secs + " "+ gt.gettext('seconds');
			} else if (hours>0) {
					var elapsed_time=hours + " "+ gt.gettext('hours')+", " + mins + " "+ gt.gettext('minutes')+", and " + secs + " "+ gt.gettext('seconds');
				} else if (mins>0) {
						var elapsed_time=mins + " "+ gt.gettext('minutes')+", and " + secs + " "+ gt.gettext('seconds');
					} else {
						var elapsed_time=secs + " "+ gt.gettext('seconds');
					}
        return elapsed_time;
    }
function gmdate (format, timestamp) {
    // Format a GMT date/time 
    //
    // version: 905.3122
    // discuss at: http://phpjs.org/functions/gmdate
    // +   original by: Brett Zamir (http://brett-zamir.me)
    // -    depends on: date
    // *     example 1: gmdate('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400); // Return will depend on your timezone
    // *     returns 1: '07:09:40 m is month'
    var dt = ((typeof(timestamp) == 'undefined') ? new Date() : // Not provided
        (typeof(timestamp) == 'number') ? new Date(timestamp*1000) : // UNIX timestamp
        new Date(timestamp));
    timestamp = Date.parse(dt.toUTCString().slice(0, -4))/1000;
    return this.date(format, timestamp);
}
function date ( format, timestamp ) {
    // Format a local date/time  
    // 
    // version: 905.3122
    // discuss at: http://phpjs.org/functions/date
    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: MeEtc (http://yass.meetcweb.com)
    // +   improved by: Brad Touesnard
    // +   improved by: Tim Wiel
    // +   improved by: Bryan Elliott
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: David Randall
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   derived from: gettimeofday
    // %        note 1: Uses global: php_js to store the default timezone
    // *     example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
    // *     returns 1: '09:09:40 m is month'
    // *     example 2: date('F j, Y, g:i a', 1062462400);
    // *     returns 2: 'September 2, 2003, 2:26 am'
    // *     example 3: date('Y W o', 1062462400);
    // *     returns 3: '2003 36 2003'
    // *     example 4: x = date('Y m d', (new Date()).getTime()/1000); // 2009 01 09
    // *     example 4: (x+'').length == 10
    // *     returns 4: true
    var jsdate=(
        (typeof(timestamp) == 'undefined') ? new Date() : // Not provided
        (typeof(timestamp) == 'number') ? new Date(timestamp*1000) : // UNIX timestamp
        new Date(timestamp) // Javascript Date()
    ); // , tal=[]
    var pad = function(n, c){
        if( (n = n + "").length < c ) {
            return new Array(++c - n.length).join("0") + n;
        } else {
            return n;
        }
    };
    var _dst = function (t) {
        // Calculate Daylight Saving Time (derived from gettimeofday() code)
        var dst=0;
        var jan1 = new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0);  // jan 1st
        var june1 = new Date(t.getFullYear(), 6, 1, 0, 0, 0, 0); // june 1st
        var temp = jan1.toUTCString();
        var jan2 = new Date(temp.slice(0, temp.lastIndexOf(' ')-1));
        temp = june1.toUTCString();
        var june2 = new Date(temp.slice(0, temp.lastIndexOf(' ')-1));
        var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60);
        var daylight_time_offset = (june1 - june2) / (1000 * 60 * 60);

        if (std_time_offset === daylight_time_offset) {
            dst = 0; // daylight savings time is NOT observed
        }
        else {
            // positive is southern, negative is northern hemisphere
            var hemisphere = std_time_offset - daylight_time_offset;
            if (hemisphere >= 0) {
                std_time_offset = daylight_time_offset;
            }
            dst = 1; // daylight savings time is observed
        }
        return dst;
    };
    var ret = '';
    var txt_weekdays = ["Sunday","Monday","Tuesday","Wednesday",
        "Thursday","Friday","Saturday"];
    var txt_ordin = {1:"st",2:"nd",3:"rd",21:"st",22:"nd",23:"rd",31:"st"};
    var txt_months =  ["", "January", "February", "March", "April",
        "May", "June", "July", "August", "September", "October", "November",
        "December"];

    var f = {
        // Day
            d: function(){
                return pad(f.j(), 2);
            },
            D: function(){
                var t = f.l();
                return t.substr(0,3);
            },
            j: function(){
                return jsdate.getDate();
            },
            l: function(){
                return txt_weekdays[f.w()];
            },
            N: function(){
                return f.w() + 1;
            },
            S: function(){
                return txt_ordin[f.j()] ? txt_ordin[f.j()] : 'th';
            },
            w: function(){
                return jsdate.getDay();
            },
            z: function(){
                return (jsdate - new Date(jsdate.getFullYear() + "/1/1")) / 864e5 >> 0;
            },

        // Week
            W: function(){
                var a = f.z(), b = 364 + f.L() - a;
                var nd2, nd = (new Date(jsdate.getFullYear() + "/1/1").getDay() || 7) - 1;

                if(b <= 2 && ((jsdate.getDay() || 7) - 1) <= 2 - b){
                    return 1;
                } 
                if(a <= 2 && nd >= 4 && a >= (6 - nd)){
                    nd2 = new Date(jsdate.getFullYear() - 1 + "/12/31");
                    return date("W", Math.round(nd2.getTime()/1000));
                }
                return (1 + (nd <= 3 ? ((a + nd) / 7) : (a - (7 - nd)) / 7) >> 0);
            },

        // Month
            F: function(){
                return txt_months[f.n()];
            },
            m: function(){
                return pad(f.n(), 2);
            },
            M: function(){
                var t = f.F();
                return t.substr(0,3);
            },
            n: function(){
                return jsdate.getMonth() + 1;
            },
            t: function(){
                var n;
                if( (n = jsdate.getMonth() + 1) == 2 ){
                    return 28 + f.L();
                }
                if( n & 1 && n < 8 || !(n & 1) && n > 7 ){
                    return 31;
                }
                return 30;
            },

        // Year
            L: function(){
                var y = f.Y();
                return (!(y & 3) && (y % 1e2 || !(y % 4e2))) ? 1 : 0;
            },
            o: function(){
                if (f.n() === 12 && f.W() === 1) {
                    return jsdate.getFullYear()+1;
                }
                if (f.n() === 1 && f.W() >= 52) {
                    return jsdate.getFullYear()-1;
                }
                return jsdate.getFullYear();
            },
            Y: function(){
                return jsdate.getFullYear();
            },
            y: function(){
                return (jsdate.getFullYear() + "").slice(2);
            },

        // Time
            a: function(){
                return jsdate.getHours() > 11 ? "pm" : "am";
            },
            A: function(){
                return f.a().toUpperCase();
            },
            B: function(){
                // peter paul koch:
                var off = (jsdate.getTimezoneOffset() + 60)*60;
                var theSeconds = (jsdate.getHours() * 3600) +
                                 (jsdate.getMinutes() * 60) +
                                  jsdate.getSeconds() + off;
                var beat = Math.floor(theSeconds/86.4);
                if (beat > 1000) {
                    beat -= 1000;
                }
                if (beat < 0) {
                    beat += 1000;
                }
                if ((String(beat)).length == 1) {
                    beat = "00"+beat;
                }
                if ((String(beat)).length == 2) {
                    beat = "0"+beat;
                }
                return beat;
            },
            g: function(){
                return jsdate.getHours() % 12 || 12;
            },
            G: function(){
                return jsdate.getHours();
            },
            h: function(){
                return pad(f.g(), 2);
            },
            H: function(){
                return pad(jsdate.getHours(), 2);
            },
            i: function(){
                return pad(jsdate.getMinutes(), 2);
            },
            s: function(){
                return pad(jsdate.getSeconds(), 2);
            },
            u: function(){
                return pad(jsdate.getMilliseconds()*1000, 6);
            },

        // Timezone
            e: function () {
/*                var abbr='', i=0;
                if (this.php_js && this.php_js.default_timezone) {
                    return this.php_js.default_timezone;
                }
                if (!tal.length) {
                    tal = timezone_abbreviations_list();
                }
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].offset === -jsdate.getTimezoneOffset()*60) {
                            return tal[abbr][i].timezone_id;
                        }
                    }
                }
*/
                return 'UTC';
            },
            I: function(){
                return _dst(jsdate);
            },
            O: function(){
               var t = pad(Math.abs(jsdate.getTimezoneOffset()/60*100), 4);
               t = (jsdate.getTimezoneOffset() > 0) ? "-"+t : "+"+t;
               return t;
            },
            P: function(){
                var O = f.O();
                return (O.substr(0, 3) + ":" + O.substr(3, 2));
            },
            T: function () {
/*                var abbr='', i=0;
                if (!tal.length) {
                    tal = timezone_abbreviations_list();
                }
                if (this.php_js && this.php_js.default_timezone) {
                    for (abbr in tal) {
                        for (i=0; i < tal[abbr].length; i++) {
                            if (tal[abbr][i].timezone_id === this.php_js.default_timezone) {
                                return abbr.toUpperCase();
                            }
                        }
                    }
                }
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].offset === -jsdate.getTimezoneOffset()*60) {
                            return abbr.toUpperCase();
                        }
                    }
                }
*/
                return 'UTC';
            },
            Z: function(){
               return -jsdate.getTimezoneOffset()*60;
            },

        // Full Date/Time
            c: function(){
                return f.Y() + "-" + f.m() + "-" + f.d() + "T" + f.h() + ":" + f.i() + ":" + f.s() + f.P();
            },
            r: function(){
                return f.D()+', '+f.d()+' '+f.M()+' '+f.Y()+' '+f.H()+':'+f.i()+':'+f.s()+' '+f.O();
            },
            U: function(){
                return Math.round(jsdate.getTime()/1000);
            }
    };

    return format.replace(/[\\]?([a-zA-Z])/g, function(t, s){
        if( t!=s ){
            // escaped
            ret = s;
        } else if( f[s] ){
            // a date function exists
            ret = f[s]();
        } else{
            // nothing special
            ret = s;
        }
        return ret;
    });
}
function deg2rad(angle) {
    // Converts the number in degrees to the radian equivalent  
    // 
    // version: 810.114
    // discuss at: http://phpjs.org/functions/deg2rad
    // +   original by: Enrique Gonzalez
    // *     example 1: deg2rad(45);
    // *     returns 1: 0.7853981633974483
    
    return (angle/180)*Math.PI;
}
function cos(arg) {
    // Returns the cosine of the number in radians  
    // 
    // version: 810.114
    // discuss at: http://phpjs.org/functions/cos
    // +   original by: Onno Marsman
    // *     example 1: cos(8723321.4);
    // *     returns 1: -0.18127180117607017
    return Math.cos(arg);
}
function sin(arg) {
    // Returns the sine of the number in radians  
    // 
    // version: 810.114
    // discuss at: http://phpjs.org/functions/sin
    // +   original by: Onno Marsman
    // *     example 1: sin(8723321.4);
    // *     returns 1: -0.9834330348825909
    return Math.sin(arg);
}
function rad2deg(angle) {
    // Converts the radian number to the equivalent number in degrees  
    // 
    // version: 810.117
    // discuss at: http://phpjs.org/functions/rad2deg
    // +   original by: Enrique Gonzalez
    // *     example 1: rad2deg(3.141592653589793);
    // *     returns 1: 180
    
    return (angle/Math.PI) * 180;
}
function acos(arg) {
    // Return the arc cosine of the number in radians  
    // 
    // version: 810.114
    // discuss at: http://phpjs.org/functions/acos
    // +   original by: Onno Marsman
    // *     example 1: acos(0.3);
    // *     returns 1: 1.2661036727794992
    return Math.acos(arg);
}
function strtoupper( str ) {
    // Makes a string uppercase  
    // 
    // version: 810.114
    // discuss at: http://phpjs.org/functions/strtoupper
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Onno Marsman
    // *     example 1: strtoupper('Kevin van Zonneveld');
    // *     returns 1: 'KEVIN VAN ZONNEVELD'
    return (str+'').toUpperCase();
}
function setPosOnGrid(currentRowIdx) {

			//Ext.getCmp('TripPositionEG').getStore().load();
			//Ext.getCmp('TripPositionEG').getUpdater().refresh();
			//setTimeout(function(){Ext.getCmp('TripPositionEG').getView().focusRow( currentRowIdx )},3000);
			Ext.getCmp('TripPositionEG').getView().focusRow( currentRowIdx );
			Ext.getCmp('TripPositionEG').getUpdater().refresh();
			//TripPositionEG.getView().focusEl.focus();

			//Ext.Msg.alert("Position ID","id is \""+pid+ "\" row should turn green"); 

  } 


//Function to handle editing of Trip Header Information.

/**
 * Handler to control grid editing
 * @param {Object} oGrid_Event
 */
function handleEdit(editEvent) {
	//determine what column is being edited
	var gridField = editEvent.field;
	//start the process to update the db with cell contents
	updateDB(editEvent);
	//I don't want to wait for server update to update the Total Column
	if (gridField == 'price'){
		getTax(editEvent);//start the process to update the Tax Field
	}
}

function updateDB(oGrid_Event) {

			if (oGrid_Event.value instanceof Date) {
				//format the value for easy insertion into MySQL
				var fieldValue = oGrid_Event.value.format('Y-m-d H:i:s');
			} else {
				var fieldValue = oGrid_Event.value;
			}	
					
			//submit to server
            Ext.Ajax.request( //alternative to Ext.form.FormPanel? or Ext.BasicForm
                {   //Specify options (note success/failure below that
                    //receives these same options)
                    waitMsg: 'Saving changes...',
                    //url where to send request (url to server side script)
                    url: 'handler.php', 
					
					//If specify params default is 'POST' instead of 'GET'
                    //method: 'POST', 
					
					//params will be available server side via $_POST or $_REQUEST:
                    params: { 
                        mode: "posupdate", //pass task to do to the server script
                        key: 'ID',//pass to server same 'id' that the reader used
                        table:"positions",
						//For existing records this is the unique id (we need
						//this one to relate to the db). We'll check this
						//server side to see if it is a new record                    
                        keyID: oGrid_Event.record.data.ID,
						
						//For new records Ext creates a number here unrelated
						//to the database
					    //-bogusID: oGrid_Event.record.id,

                        field: oGrid_Event.field,//the column name
                        value: fieldValue,//the updated value
                        
						//The original value (oGrid_Event.orginalValue does
						//not work for some reason) this might(?) be a way
						//to 'undo' changes other than by cookie? When the
						//response comes back from the server can we make an
						//undo array?                         
                        originalValue: oGrid_Event.record.modified
						
                    },//end params
                    
					//the function to be called upon failure of the request
					//(404 error etc, ***NOT*** success=false)
                    failure:function(response,options){
                        Ext.MessageBox.alert('Warning','Oops...');
                        //ds.rejectChanges();//undo any changes
                    },//end failure block      
                    
					//The function to be called upon success of the request                                
                    success:function(response,options){
						//Ext.MessageBox.alert('Success','Yeah...');
                   
						
						//if this is a new record need special handling
						if(oGrid_Event.record.data.ID == 0){
							var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server
							
							//Extract the ID provided by the server
							var newID = responseData.newID;
							//oGrid_Event.record.id = newID;
							
							//Reset the indicator since update succeeded
							oGrid_Event.record.set('newRecord','no');
							
							//Assign the id to the record
							oGrid_Event.record.set('ID',newID);
							//Note the set() calls do not trigger everything
							//since you may need to update multiple fields for
							//example. So you still need to call commitChanges()
							//to start the event flow to fire things like
							//refreshRow()
							
							//commit changes (removes the red triangle which
							//indicates a 'dirty' field)
							TripPositionDS.commitChanges();

						    //var whatIsTheID = oGrid_Event.record.modified;
						
						//not a new record so just commit changes	
						} else {
							//commit changes (removes the red triangle
							//which indicates a 'dirty' field)
							TripPositionDS.commitChanges();
						}
                    }//end success block                                      
                 }//end request config
            ); //end request  
        } //end updateDB 

function tripedit(uid,tid) {

//	Ext.MessageBox.alert('Trip ID',uid);
	
	trip_data = new Ext.data.Store({
		id: 'trip_data',
		proxy: new Ext.data.HttpProxy({
					url: 'handler.php',      // File to connect to
					method: 'POST'
					}),
					baseParams:{mode: "TripSelect"},
		reader: new Ext.data.JsonReader({
					root: 'results',
					totalProperty: 'total',
					id: 'id'
					},[				
						{name: 'ID', type: 'int', mapping: 'ID'},
						{name: 'FK_Users_ID', type: 'int', mapping: 'FK_Users_ID'},
						{name: 'Name', type: 'string', mapping: 'Name'},
						{name: 'Comments', type: 'string', mapping: 'Comments'},
						{name: 'MinDate', type: 'string', mapping: 'MinDate'},
						{name: 'MaxDate', type: 'string', mapping: 'MaxDate'}
					]),
		remoteSort: false
	});

	var trip_id = new Ext.form.TextField({
		fieldLabel	: gt.gettext('Trip ID'),
		name		: 'ID',
		anchor		: '95%',
		disabled	: true,
		grow		: true
    });	
	var user_id = new Ext.form.TextField({
        fieldLabel	: gt.gettext('User ID'),
        name		: 'FK_Users_ID',
		anchor		: '95%',
		disabled	: true,
		grow		: true
    });	
	var trip_name = new Ext.form.TextField({
		fieldLabel	: gt.gettext('Trip Name'),
		name		: 'Name',
		anchor		: '95%'
//		grow		: true
		});	
	var trip_comments_edit = new Ext.form.TextArea({
		fieldLabel	: gt.gettext('Comments'),
		name		: 'Comments',
		anchor		: '95%'
//		grow		: true
    });	
//Edit Trip Header Information 
	var editTripform = new Ext.form.FormPanel({
//        title: 'Trip Information',
//        modal:true,
        shadow:true,
        width: '100%',
        height: '100%',
//        proxyDrag: true,
//        closable:true,
 //       plain:true,
//        layout: 'fit',
        items:[trip_id, user_id, trip_name, trip_comments_edit]
	});

	editTripDialog = new Ext.Window({
			title: gt.gettext('Trip Information'),
			layout:'form',
			modal:true,
			top: 200,
			width: 500,
			height: 250,
//			minWidth:200,
//			minHeight:350,
//			resizable : true,
			bodyStyle:'padding:5px;',
			items: editTripform
	});
	
	editTripDialog.addButton({
		text	:	gt.gettext('Cancel'),
		scope	:	this,
		handler	:	function(){
			editTripDialog.destroy();
		}
	});
	editTripDialog.addButton({
		text	:	gt.gettext('Save'),
		scope	:	this,
		handler	:	function(){
			tid = trip_id.getValue();
			uid = user_id.getValue();
			var tname = trip_name.getValue();
			var tcomments = trip_comments_edit.getValue();
			//submit to server
            Ext.Ajax.request( 
                {   //Specify options (note success/failure below that
                    //receives these same options)
                    waitMsg: gt.gettext('SavingMessage'),
                    //url where to send request (url to server side script)
                    url: 'handler.php', 
					//params will be available server side via $_POST or $_REQUEST:
                    params: { 
                        mode: 'TripUpdateHeader', //pass task to do to the server script
                        UID: uid,                   
                        TID: tid,
                        TName: tname,//the column name
                        TComments: tcomments//the updated value
                     },//end params
                    
					//the function to be called upon failure of the request
                    failure:function(response,options){
                        Ext.MessageBox.alert('Warning','Oops...');
                        //ds.rejectChanges();//undo any changes
                    },//end failure block      
					//The function to be called upon success of the request                                
                    success:function(response,options){
						editTripDialog.destroy();//close this window
						TripDataDS.load(); // reload the data store
						var tcbo = Ext.getCmp('TripListcbo');
						var tcom = Ext.getCmp('trip_comments');
						//tcbo.focus();  // will set the focus to combo box and make it drop down
						tcbo.selectByValue(tname);
						tcom.setValue(tcomments);
						

                    }//end success block                                      
                 }//end request config
			);
		}
	});
				
trip_data.load({params: {
						TID: tid,
						UID: uid
						}
					});
					
trip_data.on('load', function() {
		editTripDialog.show();		
		trip_id.setValue(trip_data.getAt(0).data.ID);
		user_id.setValue(trip_data.getAt(0).data.FK_Users_ID);
		trip_name.setValue(trip_data.getAt(0).data.Name);
		trip_comments_edit.setValue(trip_data.getAt(0).data.Comments);
});

}
// end form Trip Selection


