/*
* MapBuilder Integrator 2.1.0
* Copyright(c) 2006-2007, Mashup Technologies, LLC.
* http://mashuptechnologies.com
*/

/* Redefine ugly BLANK_IMAGE_URL to use origin domain instead if extjs.com */
Ext.BLANK_IMAGE_URL = '/libs/ext/2.0.1/resources/images/default/s.gif';

//Register app.se32bj namespace
Ext.namespace('MapObject.app.vc');


/* 
* Overwrite MapViewer.dsLoad to work with a tree structure.
*/
MapObject.widget.MapViewer.prototype.dsLoad = function (ds) {
	//Remove old staff
	this.mapViewer.getMapProxy().activeMarker = null;

	// Center map
	var mapData = this.ds.reader.jsonData.map;
	this.mapViewer.defaultZoom = parseInt(mapData.zoom);
	this.mapViewer.getMapProxy().setCenter(parseFloat(mapData.lat), parseFloat(mapData.lng), this.mapViewer.defaultZoom); 
	// Save map position
	this.mapViewer.getMapProxy().mapObject.savePosition();
			
	// Build icons
	this.mapViewer.buildIcons(this.ds.reader.jsonData.icons);

	function processDetails(record)
	{
		var markers = record.get('markers');
		for(var i=0, len=markers.length; i<len; i++) {
			var activeMarker = markers[i];
			// Add locations to a map
			var id = activeMarker.id;
			var lat = activeMarker.lat;
			var lng = activeMarker.lng;
			// Add marker
			this.mapViewer.getMapProxy().addMarker(id, lat, lng, this.mapViewer.iconsSet[activeMarker.iconname]);
		}
	}

	// Process data store records
	this.ds.each(processDetails, this);

	// Run a hook method
	this.postDSLoadHook(ds);
				
	/* Use overlay instead 
	* //Create new marker manager
	* var mgr = new GMarkerManager(this.mapViewer.getMapProxy().mapObject);
	* mgr.addMarkers(batch, '9');
	* mgr.refresh();
	*/

};

/* Storage for the last selected location */
MapObject.widget.MapViewer.prototype.lastLocation = null;
/* 
* Select location and do some highlighting
* @param {mixed} string Marker id.
*/
MapObject.widget.MapViewer.prototype.setSelectedLocation = function (id, zoomIn) {
	if (this.lastLocation != null) {
		this.lastLocation.removeClass('locationSelected');	
	}
	// Hignlight location row
	this.lastLocation = Ext.get('location:' + id);
	this.lastLocation.addClass('locationSelected');

	// Set active marker
	var marker = this.mapViewer.getMapProxy().getMarker(id);
	
	var proxy = this.mapViewer.getMapProxy();
	// Restore icon of previos active marker
	if (proxy.activeMarker) {
		proxy.activeMarker.setImage(proxy.activeMarker.getIcon().image);
		// Fix issue with double selection
		proxy.activeMarker = null;
	}
	proxy.setActiveMarkerIcon(marker, true);
	proxy.setActiveMarker(marker);

	// Zoom in?
	if (zoomIn) {
		this.zoomToMax(id);
	}

	/* Code moved from gridRowClick */
	var id = marker.id; 
	
	/* Do not display record details below a map
	* this.recordViewer.showDetails(id);
	*/

	this.moveIntoMapView(id);
	
}
/**
* onMarker click event. It selects grid row and fires rowclick event.
* @param {mixed} marker Record id.
* @return none
*/
MapObject.widget.MapViewer.prototype.onMarkerClick = function (marker) {

	// Find parent row id
	var parent_id = MapObject.app.vc.util.getParentID(marker.id);
	//Select a matching record on a grid
	var index = this.ds.indexOfId(parent_id);

	// Pass second argument to keep existing selection
	this.grid.getSelectionModel().selectRow(index, this.ctrlKey);

	//Expand parent row
	this.grid.plugins.expandRow(index);

	//Select location on a grid
	this.setSelectedLocation(marker.id, false);

	/* VC update 
	* this.grid.fireEvent('rowclick');
	*/
	/* EOF Code moved from gridRowClick */

	// Scroll selected row into view
	var view = this.grid.getView();
	/* Moved to Ext.grid.RowExpander.expandRow 
	* //view.getRow(index).scrollIntoView();
	*/

	/* Do not highlight and fade active row - suggested by MW, 
	Ext.get(view.getRow(index)).highlight(null, {duration: 5});
	*/

	// Hide tooltip
	this.mapViewer.getMapProxy().getTooltip().style.visibility = "hidden";
	
	// Check for locations nearby
	var latLng = marker.getLatLng();
	var lat = latLng.lat();
	var lng = latLng.lng();
	
	// Show an info window popup
	this.mapViewer.getMapProxy().mapObject.openInfoWindowHtml(latLng, '<div id="info-window">' + this.tooltipTemplate.getHTML(marker.id) + 
	'<div class="smallText"><a id="zoomTo" href="javascript: MapObject.app.vc.auth.map.mapViewer.zoomToMax();">zoom to</a></div></div>' );

};


// Not sure if we need this
MapObject.widget.MapViewer.prototype.gridRowClick = function(gridRef, rowIndex, e){
	return false; 
};


/**
* Center map on record's marker.
* @param {String} id Record id.
* @return none
*/
MapObject.widget.MapViewer.prototype.moveIntoMapView = function(id) {
	this.mapViewer.getMapProxy().panTo(this.mapViewer.getMapProxy().getMarker(id));
};


/**
 * recordViewer component designed to fetch and render an information block for the individual datasource record.
 * @namespace MapObject.app.vc
 * @class recordViewer
 * @constructor
 * @param {Ext.data.Store} The instance of data source store object.
 */
 
 
MapObject.app.vc.recordViewer = function(ds)
{
	this.init(ds);
}
MapObject.app.vc.recordViewer.prototype = {

	/**
	* A detail panel HTML element
	* @private
	* @type {HTMLElement}
	*/
	detailPanel: null,

	/**
	* Details template
	* @private
	* @type {Ext.Template}
	*/
	detailsTemplate: null,

	/**
	* Data store
	* @private
	* @type {Ext.data.Store}
	*/
	ds: null,

    // Constructor
    init : function(ds){
    	this.ds = ds;

		// Detail view panels
		this.detailPanel = Ext.get('detailPanel');
      
		this.detailsTemplate = new Ext.Template(
			'<div class="details">' +
			'<table class="General" width="99%" border="0" cellspacing="0" cellpadding="2" style="padding-left:0px;">' +
			'<tr><th colspan="1" style="text-align: left;">' + 
			'{comp_name}' + 
			'<img src="/media/icons/marker_20_active.png" alt="Selected Location"/> ' + 
			'<span class="smallText"><a id="zoomTo" href="javascript: void(null);">zoom to</a></span> ' +
			'</th></tr>' + 
			'{content}' +																		
			'</table></div>'
		);
		this.detailsTemplate.compile();

    },

	/**
	* Show details for the record with specified id.
	* @param {String} record id
	* @return none
	*/
    showDetails: function(id) {

		// Find parent row id
		var parent_id = MapObject.app.vc.util.getParentID(id);

    	// Get record from data storage
    	var record = this.ds.getById(parent_id);
        var content = [];

        // find activeMarker
        var activeLocation = null;
        var markers = record.get('markers');
        for (var i=0, len=markers.length; i<len; i++) {
        	if (markers[i].id == id){
        		activeLocation = markers[i];
        		break;
        	}
        }

		var kom1 = "";
		
		if (activeLocation !== null) {
			if (activeLocation.address) content.push("<tr><td>" + activeLocation.address + "</td></tr>");
			if (activeLocation.address2) content.push("<tr><td>" +  activeLocation.address2 + "</td></tr>");
		
			if(activeLocation.city && activeLocation.state) kom1 = ", ";
			if (activeLocation.city || activeLocation.state || activeLocation.zip) 
				content.push("<tr><td>" + activeLocation.city + kom1 + activeLocation.state + " " + activeLocation.zip + "</td></tr>");
			content.push("<br/>");

			if (activeLocation.phone) content.push("<tr><td>" + activeLocation.phone + "</td></tr>");
		}
		
		if (record.get('website')) content.push("<tr><td><a href='" + record.get('website') + "'>" + record.get('website') + "</a></td></tr>");

		if (activeLocation !== null) {
			if (activeLocation.ContactEmail && (activeLocation.ContactEmail.length>3)) 
				content.push("<tr><td><a href='mailto:" + activeLocation.ContactEmail + "'>" + activeLocation.ContactEmail + "</a></td></tr>");
			if (activeLocation.BusinesEmail && (activeLocation.BusinesEmail.length>3)) 
				content.push("<tr><td><a href='mailto:" + activeLocation.BusinesEmail + "'>" + activeLocation.BusinesEmail + "</a></td></tr>");
			content.push("<br/>");
		}
		
		if (record.get('AUM')) content.push("<tr><td>" + record.get('AUM') + " million AUM</td></tr>");
		if (record.get('MinInv')) content.push("<tr><td>Invests: $" + record.get('MinInv') + " - $" + record.get('MaxInv') + "</td></tr>");				
		
		
		
		 this.detailsTemplate.overwrite(this.detailPanel, {
                       id: id,
                       comp_name: record.get('comp_name'),
                       content: content.join("\n")
               });
		
    	this.detailPanel.show();
    },

	/**
	* Hide details block.
	* @param none
	* @return none
	*/
    hide: function () {
    	this.detailPanel.hide();
    },

	// No more trailing commas issues
	EOF:null
}


/**
 * tooltipTemplate component designed to fetch and render a tooltip block for the individual datasource record.
 * @namespace MapObject.app.vc
 * @class tooltipTemplate
 * @constructor
 * @param {Ext.data.Store} The instance of data source store object.
 */
MapObject.app.vc.tooltipTemplate = function(ds)
{
	this.init(ds);
}
MapObject.app.vc.tooltipTemplate.prototype = {

	/**
	* Data store
	* @private
	* @type {Ext.data.Store}
	*/
	ds: null,

	/**
	* Tooltip template
	* @private
	* @type {Ext.Template}
	*/
	template: null,

    // Constructor
    init : function(ds){

    	this.ds = ds;// take with Ext.data.Store in {}
		this.template = new Ext.Template(
			'<div class="tooltip">' +
			'<div class="tooltip-container">' +
			'{content}' +
			'</div></div>'											
		);
		this.template.compile();

    },

	/**
	* Show a tooltip for a given record id including  nearby locations.
	* @param {String} record id
	* @return none
	*/
    getHTML: function(id) {

		var parent_id = MapObject.app.vc.util.getParentID(id);

    	var record = this.ds.getById(parent_id);

        // find activeMarker
        var activeLocation = null;
        var markers = record.get('markers');
        for (var i=0, len=markers.length; i<len; i++) {
        	if (markers[i].id == id){
        		activeLocation = markers[i];
        		break;
        	}
        }

		// Get HTML for a master record
		var html = [];
		html.push(this.getHTMLIndividual(id));


		// Master lat/lng
		var lat = activeLocation.lat;
		var lng = activeLocation.lng;
		// Loop through data source
		function processRecords(record)
		{
			var markers = record.get('markers');
		
			for(var i=0, len=markers.length; i<len; i++) {
				var new_id = markers[i].id;
				// Do not count main marker
				if (new_id != activeLocation.id) {
					var new_lat = markers[i].lat;
					var new_lng = markers[i].lng;
					// Add locations to a map
					if (( Math.abs(lat - new_lat) < 0.00001) && (Math.abs(lng - new_lng) < 0.00001) ) {
						html.push(this.getHTMLIndividual(new_id));
					}
				}
			}
		}
		// Process data store records
		this.ds.each(processRecords, this);

	    return this.template.apply(
         	{										
    		   content: html.join("\n")
			}
		);
    },


	/**
	* Show a tooltip for a given record id
	* @param {String} record id
	* @return none
	*/
    getHTMLIndividual: function(id) {

		var parent_id = MapObject.app.vc.util.getParentID(id);

    	var record = this.ds.getById(parent_id);

        // find activeMarker
        var activeLocation = null;
        var markers = record.get('markers');
        for (var i=0, len=markers.length; i<len; i++) {
        	if (markers[i].id == id){
        		activeLocation = markers[i];
        		break;
        	}
        }

		var content = [];
		var kom1 = "";
		if (!Ext.isEmpty(record.get('comp_name'))) content.push("<h2>" + record.get('comp_name') + "</h2>");
		if (!Ext.isEmpty(activeLocation.address)) content.push("<span>" + activeLocation.address + "</span><br/>");
		if (!Ext.isEmpty(activeLocation.address2)) content.push("<span>" + activeLocation.address2 + "</span><br/>");
		
		if(activeLocation.city && activeLocation.state) kom1 = ", ";
		if (activeLocation.city || activeLocation.state || activeLocation.zip) 
			content.push("<span>" + activeLocation.city + kom1 + activeLocation.state + " " + activeLocation.zip + "</span><br/>");
		content.push("<br/>");

		if (!Ext.isEmpty(activeLocation.phone)) 
			content.push("<span>" + activeLocation.phone + "</span><br/>");
		
		var website = record.get('website');
		if (!Ext.isEmpty(website)) {
			//content.push("<span><a href='" + website + "'>" + website + "</a></span><br/>");
			content.push('<a href="' + website + '" target="new" onMouseOver="doTooltip(event,\'' + website + '\')" onMouseOut="hideTip()">Website</a><br/>');
		}

		if (activeLocation.ContactEmail && (activeLocation.ContactEmail.length>3)) { 
			//content.push("<span><a href='mailto:" + activeLocation.ContactEmail + "'>" + activeLocation.ContactEmail + "</a></span><br/>");
			content.push('<a href="mailto:' + activeLocation.ContactEmail + '" target="new" onMouseOver="doTooltip(event,\'' + activeLocation.ContactEmail + '\')" onMouseOut="hideTip()">Email</a>&nbsp;');
		}
		if (activeLocation.BusinesEmail && (activeLocation.BusinesEmail.length>3)) {
			//content.push("<span><a href='mailto:" + activeLocation.BusinesEmail + "'>" + activeLocation.BusinesEmail + "</a></span><br/>");
			content.push('<a href="mailto:' + activeLocation.BusinesEmail + '" target="new" onMouseOver="doTooltip(event,\'' + activeLocation.BusinesEmail + '\')" onMouseOut="hideTip()">Email2</a>');
		}

		content.push("<br/>");

		if (record.get('AUM') && !Ext.isEmpty(record.get('AUM')) && (record.get('AUM')!= 'N/A')) {
			content.push("<span>Assets Managed: $" + record.get('AUM') + " MM</span><br/>");
		}
		if (record.get('MinInv') && !Ext.isEmpty(record.get('MinInv')) && (record.get('MinInv')!= 'N/A')) {
			content.push("<span>Invests: $" + record.get('MinInv') + " - $" + record.get('MaxInv') + " MM</span><br/>");
		}

	    return content.join("\n");
    },

	/**
	* Hide the tooltip block.
	* @param none
	* @return none
	*/
    hide: function () {
    },

	// No more trailing commas issues
	EOF:null
}



MapObject.app.vc.map = function() {
	this.init();
}

MapObject.app.vc.map.prototype = {

	/**
	* Instance of map viewer
	* @private
	* @type {MapObject.widget.MapViewer}
	*/
	mapViewer: null,

	/**
	* Data store
	* @private
	* @type {Ext.data.Store}
	*/
	ds: null,

	/**
	* Grid
	* @private
	* @type {Ext.grid.Grid}
	*/
	grid: null,

	/**
	* Record Viewer
	* @private
	* @type {MapObject.app.vc.recordViewer}
	*/
	recordViewer: null,

	/**
	* Record Viewer
	* @private
	* @type {MapObject.app.vc.tooltipTemplate}
	*/
	tooltipTemplate: null,

	/**
	* Max number of waypoints used for directions generation.
	* See http://groups.google.com/group/Google-Maps-API/browse_thread/thread/5a4171dc5ec11551#19bb341d84d8cd9f
	* @private
	* @type {int}
	*/
	directionsMax: 23,

	/**
	* Indicates if data feed has been loaded at least one.
	* @private
	* @type {boolean}
	*/
	dataInitialized: false,

	/**
	* Storage for the "Tips for Best Use" window object
	* @private
	* @type {Ext.Window}
	*/
	tipsWin: null,
	
	/**
	* Initialize object
	* @param none
	* @return none
	*/
    init : function(){
    	// Display message on initial load only - use CookieProvider to control state
        Ext.state.Manager.setProvider(new Ext.state.CookieProvider( { expires: new Date(new Date().getTime()+(1000*60*60*24*3000)) }));

        if(Ext.state.Manager.getProvider().get('initialLoad', 'yes') == 'yes')
        {
          Ext.state.Manager.getProvider().set('initialLoad', 'no');
          Ext.MessageBox.alert('Welcome', "Welcome to VCDB, the Venture Capital Database.<br><br>Sometimes venture capital can be a little intimidating.  It's hard to know where to start and whom to approach.  And it can be hard to cut through the noise in order to reach investors.  I hope this application helps.<br><br>By aggregating biographical, and other basic information on many of the venture investors located in the US, a simple search can take you one step closer to funding.  If you're an investor, prospective VC, or startup enthusiast, you'll find value too.<br><br>Give it a shot and let me know what you think.  And of course, if you're running or know of an interesting startup, I'd like to hear about it.  Reach me via the \"Contact\" link in the header or \"Submit your business plan\" link in the footer.<br><br>Best,<br>Matt", completeInit.createDelegate(this));
        }
        else
        {
        	// Bind completeInit to 'this' and execute
			completeInit.createDelegate(this)();
        }

        function completeInit() {

    	//
    	// Data Store
    	//
    	// Define the Data Store
		this.ds = new Ext.data.Store({
			// load using script tags for cross domain, if the data in on the same domain as
			// this page, an HttpProxy would be better
			//proxy: new Ext.data.ScriptTagProxy({
			// Use XML HTML Request
			proxy: new Ext.data.HttpProxy({
				url: 'service/propertyList-v2.php',
				nocache: true,
				disableCaching: true
			}),
			/* Search Parameters */
	        baseParams: {test:false},

			// create reader that reads the markers
			reader: new Ext.data.JsonReader({
				root: 'companyList',
				/* totalProperty: 'totalCount', */
				id: 'id'
			}, [
				// Make sure id is present as a part of record
				{name: 'id', mapping: 'id'},
				{name: 'lat', type: 'float'},
				{name: 'lng', type: 'float'},
				{name: 'comp_name', mapping: 'comp_name'},
				{name: 'website', mapping: 'website'},
				{name: 'AUM', mapping: 'AUM', type: 'float'},
				{name: 'MinInv', mapping: 'MinInv', type: 'float'},
				{name: 'MaxInv', mapping: 'MaxInv', type: 'float'},
				{name: 'blog', mapping: 'Blog'},
				{name: 'comment', mapping: 'comment'},
				{name: 'type', mapping: 'type'},
				{name: 'ContactEmail', mapping: 'ContactEmail'},
				{name: 'BusinesEmail', mapping: 'BusinesEmail'},
				{name: 'icon', mapping: 'iconname'},
				{name: 'address', mapping: 'address'},
				{name: 'address2', mapping: 'address2'},
				{name: 'city', mapping: 'city'},
				{name: 'zip', mapping: 'zip'},
				{name: 'state', mapping: 'state'},
				{name: 'phone', mapping: 'phone'},
				{name: 'ProfNum', mapping: 'ProfNum', type: 'int'},
				{name: 'prof', mapping: 'Prof'},
				{name: 'markers', mapping: 'markers'},
				{name: 'locNum', mapping: 'locNum', type: 'int'}
			])
		});


		/*
		* beforeload Event - Fires before a request is made for a new data object.
		* If the beforeload handler returns false the load action will be canceled.
		*
		* Main responsibility of this hook is to pass search criteria to the server.
		* searchQuery: fieldRep=Select...&address=&zip=&census=&date1=&date2=&owner=Select...&employer=Select...&focus=Select...&ADF_Gap=&construction=Select...
		*/
		function beforeload(options) {
			// Update URL
			this.ds.proxy.conn.url = 'service/propertyList-v2.php?nocache=' + (new Date().getTime());

			//Serialize form and send parameters to a server
			options.baseParams.searchQuery = Ext.Ajax.serializeForm('searchForm');

			// Hide BIO panel
			if (MapObject.app.vc.bioViewer.detailPanel) {
				MapObject.app.vc.bioViewer.detailPanel.hide();
			}
			return true;
		}
		this.ds.on('beforeload', beforeload, this);


		this.ds.on('load', function(ds) {
			// Show errors
			if (this.dataInitialized && ds.reader.jsonData.errors && ds.reader.jsonData.errors.length > 0) {
				alert(ds.reader.jsonData.errors.join("\n"));
		    }
		    // Sat dataInitialized flag to true.
		    this.dataInitialized = true;

		}, this);


    	//
    	// Grid
    	//

		// RowSelectionModel
		// extjs2 var sm = new Ext.grid.RowSelectionModel({singleSelect:true});
			    

		// row expander
		var expander = new MapObject.app.vc.RowExpander({
			tpl : new Ext.Template(
				'{addressLine}',
				'{emailLineObsolete}',
				'&nbsp;<a href="{website}" target="new" onMouseOver="doTooltip(event,\'{website}\')" onMouseOut="hideTip()"><img src="/vcdb/media/icons/fam/world.png" border="0"></a> &nbsp;<a href="{website}" target="new" onMouseOver="doTooltip(event,\'{website}\')" onMouseOut="hideTip()">Website</a>{emailLine}<BR/>',
	            '{locHTML}',
	            '{profHTML}'
			),
			// Pass additional template to describe locations
			loctpl : new Ext.Template(
				'{Address}'
			),
			// Pass additional template to describe proffesionals
			proftpl : new Ext.Template(
				'{Name}, {Title}, {Blog}'
			),
			singleExpand: true
		});

		// the DefaultColumnModel expects this blob to define columns. It can be extended to provide
        // custom or reusable ColumnModels
        var colModel = new Ext.grid.ColumnModel([
        	expander,
			/* We do not use internal 'id' column anymore
			* {id: "id", header: "ID", width: 70, sortable: false, dataIndex: 'id', hidden:true },
			*/
			{id:'name', header: "Firm", width: 180, sortable: true, hideable: false, renderer: companyRenderer, dataIndex: 'comp_name'},
			{header: "Locations",  width: 60, sortable: true, dataIndex: 'locNum'},
			{header: "Professionals", width: 60, sortable: true, dataIndex: 'ProfNum'},			
			{header: "AUM", hidden: true, width: 50, sortable: true, dataIndex: 'AUM', renderer: floatRenderer},
			{header: "Min. Inv", hidden: true, width: 50, sortable: true, dataIndex: 'MinInv', renderer: floatRenderer},
			{header: "Max. Inv", hidden: true, width: 50, sortable: true, dataIndex: 'MaxInv', renderer: floatRenderer}
		]);

		// Custom renderer function to render Company, City
		function companyRenderer(v, p, record){
			return v + ( Ext.isEmpty(record.get("city").trim()) ? '' : ', '+ record.get("city"));
		}
		// Custom renderer function to render empty float values like N/A
		function floatRenderer(v, p, record){
			var formatted = Ext.util.Format.usMoney(v); // format: $1,234.00
			//return isNaN(v) ? 'N/A' : ((Ext.isEmpty(v) || (v == 0)) ? 'N/A' : formatted.substr(1, formatted.length - 4));
			return isNaN(v) ? 'N/A' : ((Ext.isEmpty(v) || (v == 0)) ? 'N/A' : v);
		}
		
		// Set custom renderer for a "Customer Name" column
		//colModel.setRenderer(colModel.getIndexById('name'), function (value, p, record) {
		//	return value + ", " + record.data['f_name'];
		//});

        // create the Grid
        this.grid = new Ext.grid.GridPanel({
        	renderTo: 'listingGrid',
            store: this.ds,
            cm: colModel,
	        /* title:'Location Listing', */
			width:468,
			height:400,
			viewConfig: {
				forceFit:true
			},
			plugins: expander,
			collapsible: true,
			animCollapse: false,
			loadMask: true,
            /*autoExpandColumn: 'Address' */
			EOF: null
        });

        // Define rowclick event to hide bioPanel content
		this.grid.on('rowclick', 
			function(gridRef, rowIndex, e){ 
			// Detail view panels
			var detailPanel = Ext.get('bioPanel');
			detailPanel.hide();

			var target = e.getTarget();
			// Check if user clicked on a '+' or '-' 
	        if((target.className != 'x-grid3-row-expander') && (target.className != 'x-grid3-td-expander')){
				// Expand row
				this.grid.plugins.toggleToExpandRow(rowIndex);
			}
		}, this);

        /* Do not use record viewer.
        * // Record viewer
        * this.recordViewer = new MapObject.app.vc.recordViewer(this.ds);
        */
        this.recordViewer = null;

        // Record viewer
        this.tooltipTemplate = new MapObject.app.vc.tooltipTemplate(this.ds);

		// Instantiate MapViewer class
		this.mapViewer = new MapObject.widget.MapViewer( {
			'ds': this.ds,
			'grid': this.grid,
			'recordViewer': this.recordViewer,
			'tooltipTemplate': this.tooltipTemplate,
			'mapConfig' : {
				'container' : 'mapContainer',
				'mapControls' : {
					// Creates a control with buttons to pan in four directions, and zoom in and zoom out.
					smallMapControl: false,
					// 	Creates a control with buttons to pan in four directions, and zoom in and zoom out, and a zoom slider.
					largeMapControl: true,
					// Creates a control with buttons to zoom in and zoom out.
					smallZoomControl: false,
					// Creates a control that displays the map scale.
					scaleControl: false
				},
				'tooltipEngine' : 'v2'
			}
		});
		this.mapViewer.messages.headerHelp = '<br>Click a column header to sort results or change header criteria.';


		// Define hook method to display results
		this.mapViewer.postDSLoadHook = function(ds) {

		    //Set rows found

			// Check total rwos count which is returned from a server
			var totalCount = parseInt(ds.reader.jsonData.totalRowsCount);
			var totalProf = parseInt(ds.reader.jsonData.totalRowsProf);
			var totalComp = parseInt(ds.reader.jsonData.totalRowsComp);
			var totalLoc = parseInt(ds.reader.jsonData.totalRowsLoc);
			
			if (totalCount == 0){
				Ext.get('gridHelp').update("0 records found. Please adjust your selection criteria.");
			}
			// Show alert message
			else if (totalCount > this.mapViewer.datasetLimit) {
				Ext.get('gridHelp').update("<b>" + totalComp + " venture firm" + ((totalCount == 1) ? "" : "s") + ", " + 
				totalLoc + " location" + ((totalCount == 1) ? "" : "s") + " " + 
				" and " + totalProf + " professional" + ((totalCount == 1) ? "" : "s") + " found.</b> " + this.mapViewer.datasetLimit + " records displayed. " + this.messages.headerHelp);
				alert ("Please adjust selection criteria to return less than " + this.mapViewer.datasetLimit + " records.");
			} 
			else { 
				Ext.get('gridHelp').update("<b>" + totalComp + " venture firm" + ((totalCount == 1) ? "" : "s") + ", " + 
				totalLoc + " location" + ((totalCount == 1) ? "" : "s") + " " + 
				" and " + totalProf + " professional" + ((totalCount == 1) ? "" : "s") + " found.</b> " + this.messages.headerHelp);
			}
		};

		var geocoder = new MapObject.proxy.GoogleGeocoder();
		// Instantiate geocoding widget
		var geocodingPanel = new MapObject.widget.GeoCodingPanel(
			'geocodeAddressInput',
			'geocodeButton',
		    geocoder,
		    this.mapViewer.getViewer('Google')
		)

		//
		// Register application events for misc. HTML elements
		//

		// Attach event to the 'search' button
                Ext.get('searchButton').on('click', function() {
                  Ext.state.Manager.getProvider().set('searchCount', Ext.state.Manager.getProvider().get('searchCount', 0) + 1);
                  if(Ext.state.Manager.getProvider().get('searchCount') == 3)
                  {
                    Ext.MessageBox.buttonText.ok = 'Submit';
                    Ext.MessageBox.buttonText.cancel = 'Nah. Not interested';
                    Ext.MessageBox.prompt('', "Here's the one and only commercial break.<br/><br/>I'd like to stay in touch, and hope you'll enter your email below to receive my blog posts, including any updates to this tool.  It won't be shared with anyone else and you can always unsubscribe.<br/><br/> ", 
                                          function(btn, text) { 
                                            if(btn == 'ok')
                                            {
			                      Ext.Ajax.request({
				                url: 'add-subscriber.php',
				                params: {
					                  'email': text
				                }
			                      });
                                            }
                                            this.search();
                                          }, this);
                    Ext.MessageBox.buttonText.ok = 'OK';
                    Ext.MessageBox.buttonText.cancel = 'Cancel';
		  }
                  else
                  {
                    this.search();
                  }
                }, this.mapViewer);

		//try {
			// Add filtering handlers
			Ext.get('mapLegend').on('click', this.filterByLegend, this);
			Ext.get('submitionLink').on('click', this.filterByLegend, this);

			// Add resetMap handler
			Ext.get('resetMap').on('click', this.mapViewer.resetMap, this.mapViewer);

			/* detailPanel display deprecated by Matt
			// Add zoomToMax event handler registered on detailPanel click
			Ext.get('detailPanel').on('click', function(e) {
				var target = e.getTarget();
				if (target.id == "zoomTo") {
					this.zoomToMax(false);
				}
			},
			this.mapViewer);
			*/

			// Register onlick event for the grid element
			Ext.get('listingGrid').on('click', function(e) {
				var target = e.getTarget();
				if (target.className == 'rowZoom') {
					var id = target.id.split(':')[1];
					//alert(id);
					this.setSelectedLocation(id, true);
				}
			},
			this.mapViewer);

			// Register onlick event for the auth elements
			Ext.get('signupLink') && Ext.get('signupLink').on('click', function(e) {
				MapObject.app.vc.auth.showForm("signup");
			});
			Ext.get('loginLink') && Ext.get('loginLink').on('click', function(e) {
				MapObject.app.vc.auth.showForm("login");
			});
		/*
		}
		catch (e) {

		}
		*/

          // Finally load data
          this.dataInitialized = false; // flag to prevent from errors output
          //CALLED IN FRAMEWORK this.ds.load();
	} // function
    },


	/**
	* Show 'Tips for Best Use' popup
	* @param none
	* @return none
	*/
	showTips: function() {
        // create the window on the first click and reuse on subsequent clicks
        if(!this.tipsWin){
            this.tipsWin = new Ext.Window({
                el:'tipsBestView',
                layout:'fit',
                autoScroll: true,
                width:700,
                height:500,
                closeAction:'hide',
                plain: true,
                modal: true,
                resizable: false,
                
                contentEl: 'tipsPanel',

                buttons: [{
                    text: 'Close',
                    handler: (function(){
                        this.tipsWin.hide();
                    }).createDelegate(this)
                }]
            });
        }
        this.tipsWin.show(this);

	},

	/**
	* Show a feedback form
	* @param none
	* @return none
	*/
	showFeedback: function() {
        // create the window on the first click and reuse on subsequent clicks
        if(!this.feedbackWin){
            this.feedbackWin = new Ext.Window({
                el:'feedback',
                layout:'fit',
                width:700,
                height:450,
                closeAction:'hide',
                plain: true,
                modal: false,
                resizable: false,
                hideMode: 'visibility',
                
                contentEl: 'feedbackPanel',
       
                buttons: [{
                    text:'Submit',
                    handler: (function(){
						var feedbackOpt = Ext.Ajax.serializeForm('feedbackForm');

						//Make ajax call and save export parameters in a session
						Ext.Ajax.request({
							url: 'service/sendFeedback.php',
							success: function (response, options) {
		                        this.feedbackWin.hide();
		                        //Remove feddback text
		                        Ext.get("feedback").dom.value = "";
						        Ext.MessageBox.alert('Feedback Status', 'Your feedback has been sent.');
							},
							failure: function () {alert("Feedback failed. Please try again.")},
							scope: this,
							params: {
								'op': feedbackOpt
							}
						});

                    }).createDelegate(this)

                },{
                    text: 'Close',
                    handler: (function(){
                        this.feedbackWin.hide();
                    }).createDelegate(this)
                }]
            });

        }
        this.feedbackWin.show(this);

	},

	/**
	* "Big" filtering
	* @param none
	* @return none
	*/
	filterLow: function() {
		Ext.get("AUM").dom.value = '1000';

		// Set search operation
		MapObject.util.Form.setSelectedValue("AUM_s", "<");

		//Remove all Records from the Store and fires the clear event.
		this.ds.removeAll();
        // Invoke search
        this.ds.load();
	},
	
		/**
	* "Big" filtering
	* @param none
	* @return none
	*/
	filterMediumLow: function() {
		Ext.get("AUM").dom.value = '3000';

		// Set search operation
		MapObject.util.Form.setSelectedValue("AUM_s", "<");

		//Remove all Records from the Store and fires the clear event.
		this.ds.removeAll();
        // Invoke search
        this.ds.load();
	},
	
		/**
	* "Big" filtering
	* @param none
	* @return none
	*/
	filterMedium: function() {
		Ext.get("AUM").dom.value = '100000';

		// Set search operation
		MapObject.util.Form.setSelectedValue("AUM_s", "<");

		//Remove all Records from the Store and fires the clear event.
		this.ds.removeAll();
        // Invoke search
        this.ds.load();
	},
	
		/**
	* "Big" filtering
	* @param none
	* @return none
	*/
	filterHigh: function() {
		Ext.get("AUM").dom.value = '10000';

		// Set search operation
		MapObject.util.Form.setSelectedValue("AUM_s", ">");

		//Remove all Records from the Store and fires the clear event.
		this.ds.removeAll();
        // Invoke search
        this.ds.load();
	},

	/**
	* Event handler to filter records by map legend
	* @param {Ext.EventObject} e
	* @return none
	*/
	filterByLegend: function(e) {
		var target = e.getTarget();

		if (target.id == "showTips") {
			this.showTips();
		}
		else if ((target.id == "showFeedback") || (target.id == "submitionLink")) {
			this.showFeedback();
		}
		
	},


    EOF: null
}


// run this function when document becomes ready
Ext.onReady(function() {
	
	var mapApp = new MapObject.app.vc.map();

	//register mapApp within
	MapObject.app.vc.auth.map = mapApp;

}); // end of onReady



/*
 * Ext JS Library 2.0
 * Copyright(c) 2006-2007, Ext JS, LLC.
 * licensing@extjs.com
 *
 * http://extjs.com/license
 */

Ext.grid.RowExpander = function(config){
    Ext.apply(this, config);

    this.addEvents({
        beforeexpand : true,
        expand: true,
        beforecollapse: true,
        collapse: true
    });

    Ext.grid.RowExpander.superclass.constructor.call(this);

    if(this.tpl){
        if(typeof this.tpl == 'string'){
            this.tpl = new Ext.Template(this.tpl);
        }
        this.tpl.compile();
    }

    this.state = {};
    this.bodyContent = {};
};

Ext.extend(Ext.grid.RowExpander, Ext.util.Observable, {
    header: "",
    width: 20,
    sortable: false,
    fixed:true,
    dataIndex: '',
    id: 'expander',
    lazyRender : true,
    enableCaching: false,
    lastExpandedRow: null,
    singleExpand: false,

    getRowClass : function(record, rowIndex, p, ds){
        p.cols = p.cols-1;
        var content = this.bodyContent[record.id];
        if(!content && !this.lazyRender){
            content = this.getBodyContent(record, rowIndex);
        }
        if(content){
            p.body = content;
        }
        return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
    },

    init : function(grid, opt){
        this.grid = grid;

        var view = grid.getView();
        view.getRowClass = this.getRowClass.createDelegate(this);

        view.enableRowBody = true;

        grid.on('render', function(){
            view.mainBody.on('mousedown', this.onMouseDown, this);
        }, this);

    },

    getBodyContent : function(record, index){
        if(!this.enableCaching){
            return this.tpl.apply(record.data);
        }
        var content = this.bodyContent[record.id];
        if(!content){
            content = this.tpl.apply(record.data);
            this.bodyContent[record.id] = content;
        }
        return content;
    },

    onMouseDown : function(e, t){
        if(t.className == 'x-grid3-row-expander'){
            e.stopEvent();
            var row = e.getTarget('.x-grid3-row');
            this.toggleRow(row);
        }
    },

    renderer : function(v, p, record){
        p.cellAttr = 'rowspan="2"';
        return '<div class="x-grid3-row-expander">&#160;</div>';
    },

    beforeExpand : function(record, body, rowIndex){
        if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){
            if(this.tpl && this.lazyRender){
                body.innerHTML = this.getBodyContent(record, rowIndex);
            }
            return true;
        }else{
            return false;
        }
    },

    toggleRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
    },

    toggleToExpandRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'expandRow'](row);
    },

    expandRow : function(row){
    	// Should we collapse alredy open row?
    	if (this.singleExpand && this.lastExpandedRow) {
    		this.collapseRow(this.lastExpandedRow);
    	}

        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        this.lastExpandedRow = row;

        var record = this.grid.store.getAt(row.rowIndex);
       
        // Record might be unavailable after data reloading
        if (!record ) return;

        var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
        if(this.beforeExpand(record, body, row.rowIndex)){
            this.state[record.id] = true;
            Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
            this.fireEvent('expand', this, record, body, row.rowIndex);

			// My custom logic: Scroll selected row into view
			//This doen't scroll to the top this.grid.view.focusRow(row.rowIndex);
			var view = this.grid.view;
			//
			var top = row.offsetTop;
	        view.scroller.dom.scrollTop = parseInt(top);

	        // Select expanded row
	        this.grid.getSelectionModel().selectRow(row.rowIndex);

			/* Code below moves browser window in FF
			if (Ext.isIE)  
				Ext.get(row).focus();
			else {
				row.scrollIntoView();
				Ext.get(row).focus();
			}
			*/
        }

    },

    collapseRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        var record = this.grid.store.getAt(row.rowIndex);
        
        // Record might be unavailable after data reloading
        if (!record ) return;

        var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
        if(this.fireEvent('beforcollapse', this, record, body, row.rowIndex) !== false){
            this.state[record.id] = false;
            Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
            this.fireEvent('collapse', this, record, body, row.rowIndex);
        }
    }
});



MapObject.app.vc.RowExpander = function(config){
    Ext.apply(this, config);

    this.addEvents({
        beforeexpand : true,
        expand: true,
        beforecollapse: true,
        collapse: true
    });

    Ext.grid.RowExpander.superclass.constructor.call(this);

    if(this.tpl){
        if(typeof this.tpl == 'string'){
            this.tpl = new Ext.Template(this.tpl);
        }
        this.tpl.compile();
    }
    if(this.loctpl){
        if(typeof this.loctpl == 'string'){
            this.loctpl = new Ext.Template(this.loctpl);
        }
        this.loctpl.compile();
    }
    if(this.proftpl){
        if(typeof this.proftpl == 'string'){
            this.proftpl = new Ext.Template(this.proftpl);
        }
        this.proftpl.compile();
    }

    
    this.state = {};
    this.bodyContent = {};
};

Ext.extend(MapObject.app.vc.RowExpander, Ext.grid.RowExpander, {
    getBodyContent : function(record, index){

    	var locHTML = []; 	// Locations info
    	var profHTML = []; 	// Proffesionals info
    	var prof = record.data.prof;
    	var locations = record.data.markers;
       
		// Create content for locations and proffesional
		for (var i = 0, len = locations.length; i < len; i++){

			var addressChain1 = []; //[address line 1], [address line 2]
			var addressChain2 = []; //[City], [State] [Zipcode]
			var addressLine = []; // addressChain1 / addressChain2
			var phoneEmailLine = []; // [phone] / [email1] / [email2]
			// email1 / email 2
			var emailLine = []

			var locData = locations[i];

			// Create address entity
			if(!Ext.isEmpty(locData.address)) addressChain1.push(locData.address);
			//if(!Ext.isEmpty(locData.address2)) addressChain1.push(locData.address2);

			//var stateZip = locData.state + ' ' +  locData.zip;
			var stateZip = locData.state;
			if(!Ext.isEmpty(locData.city)) addressChain2.push(locData.city);
			if(!Ext.isEmpty(stateZip.trim())) addressChain2.push(stateZip);

			//if(!Ext.isEmpty(addressChain1.join(','))) addressLine.push(addressChain1.join(', '));
			if(!Ext.isEmpty(addressChain2.join(','))) addressLine.push(addressChain2.join(', ')) 
			else {
				if (!Ext.isEmpty(addressChain1.join(','))) addressLine.push(addressChain1.join(', '));
			}
			// Create phone/email entity
			//if(!Ext.isEmpty(locData.phone)) phoneEmailLine.push(locData.phone);
			if(!Ext.isEmpty(locData.phone)) phoneEmailLine.push(' / <a href="#" onClick="Ext.MessageBox.alert(\'Phone\', \'\\n  '+locData.phone+'  \\n\'); return false;">Phone</a>');
			if(!Ext.isEmpty(record.data.blog)) emailLine.push('<a href="' + record.data.blog  + '" title="Blog" target="_blank">Blog</a>');
			if(!Ext.isEmpty(locData.ContactEmail) && (locData.ContactEmail.length > 3)) emailLine.push('<a href="mailto:' + locData.ContactEmail  + '" onMouseOver="doTooltip(event,\''+locData.ContactEmail+'\')" onMouseOut="hideTip()">Email</a>');
			if(!Ext.isEmpty(locData.BusinesEmail) && (locData.BusinesEmail.length > 3)) emailLine.push('<a href="mailto:' + locData.BusinesEmail  + '" onMouseOver="doTooltip(event,\''+locData.BusinesEmail+'\')" onMouseOut="hideTip()">Email 2</a>');

			// Bug - information dublicates
			//var blog = prof[i].Blog;
			//prof[i].Blog = ((blog == '') ? '' : ('<a href="' + blog + '" target="_blank">' + blog + '</a>'));

			/*
			record.data.addressLine =  addressLine.join(" / ");
			record.data.emailLine =  phoneEmailLine.join(" / ");
			if (!Ext.isEmpty(record.data.addressLine.trim())) record.data.addressLine += "<br/>";
			if (!Ext.isEmpty(record.data.emailLine.trim())) record.data.emailLine += "<br/>";
			*/

			//locHTML.push(this.loctpl.apply(prof[i]) + ' <a id="prof' + locations[i].Professional_ID + '" href="javascript: void(null);" onclick="MapObject.app.vc.bioViewer.showBio(' + prof[i].Professional_ID + ')" >View Bio</a>');
			locHTML.push('<div id="location:' + locData.id + '">' + '<a href="javascript: void(null);"><img class="rowZoom" id="rowZoom:' + locData.id + '" src="/media/icons/fam/magnifier.png" alt="Zoom In"/></a>' + addressLine.join(" / ") + " " + phoneEmailLine.join(" / ") + '</div>');
		}

		// Add emails
    	if (emailLine.length > 0) {
	    	record.data.emailLine = ' / ' + emailLine.join(' / ');
		}
		else {
			record.data.emailLine = "";
		}

		// Create content for proffesional
		for (var i = 0, len = prof.length; i < len; i++){
			// Bug - information dublicates
			var blog = prof[i].Blog;
			prof[i].Blog = ((blog == '') ? '' : ('<a title="Blog" href="' + blog + '" target="_blank">Blog</a>'));
			profHTML.push('<a href="javascript: void(null);" onclick="MapObject.app.vc.bioViewer.showBio(' + prof[i].Professional_ID + ')"><img class="rowBio" src="/media/icons/fam/user.png" alt="View Bio"/></a>' + this.proftpl.apply(prof[i]) + ' <a title="View Bio" id="prof' + prof[i].Professional_ID + '" href="javascript: void(null);" onclick="MapObject.app.vc.bioViewer.showBio(' + prof[i].Professional_ID + ')" >Bio</a>');
		}
    	
    	if (locHTML.length > 0) {
	    	record.data.locHTML =  "<b>Locations:</b>" + locHTML.join("\n");
		}
		else {
			record.data.locHTML = "";
		}

    	if (profHTML.length > 0) {
	    	record.data.profHTML =  "<b>Investment Professionals:</b><br/>" + profHTML.join("<br>");
		}
		else {
			record.data.profHTML = "";
		}

		// Do not cache 
		this.enableCaching = true;

        if(!this.enableCaching){
            return this.tpl.apply(record.data);
        }
        var content = this.bodyContent[record.id];
        if(!content){
            content = this.tpl.apply(record.data);
            this.bodyContent[record.id] = content;
        }
        return content;
    }

});


/*
* MapBuilder Integrator 2.1.0
* Copyright(c) 2006-2007, Mashup Technologies, LLC.
* http://mashuptechnologies.com
*/

MapObject.app.vc.bioViewer = {
	detailsTemplate: null,
	
	/**
	* Storage for the "Bio" window object
	* @private
	* @type {Ext.Window}
	*/
	bioWin: null,

	/*
	* Show bio popup for a proffesional with a given id
	*/
	showBio: function(id) {
		// Detail view panels
		this.detailPanel = Ext.get('bioPanel');
		//this.detailPanel.hide();

        // create the window on the first click and reuse on subsequent clicks
        if(!this.bioWin){
            this.bioWin = new Ext.Window({
                el:'bioWin',
                layout:'fit',
                autoScroll: true,
                width:600,
                height:'auto',
                closeAction:'hide',
                plain: true,
                modal: true,
                resizable: false,
                
                contentEl: 'bioPanel',

                buttons: [{
                    text: 'Close',
                    handler: (function(){
                        this.bioWin.hide();
                    }).createDelegate(this)
                }]
            });
        }
        //this.bioWin.hide();

		this.detailsTemplate = new Ext.Template(
			'<div class="details">' +
			'<b>{Name}, {Title}</b> {Blog}<br/>' +
			'<img src="http://{PhotoPath}" align="right" border="1">{Bio}' + 
			'</div>'
		);
		this.detailsTemplate.compile();

		//Make ajax call and get bio informatiom
		Ext.Ajax.request({
			url: 'service/getBio.php',
			success: (function(response, options) {
	            o = Ext.util.JSON.decode(response.responseText);

				if (o.PhotoPath == "") {
					o.PhotoPath = "www.punctuative.com/vcdb/lennygif.gif";
				}

				// Details for lease type
				this.detailsTemplate.overwrite(this.detailPanel, {
					Name: o.Name,
					Title: o.Title,
					Blog: ((o.Blog == '') ? '' : ('<a href="' + o.Blog + '" target="_blank">Blog</a>')),
					Bio: o.Bio,
					PhotoPath: o.PhotoPath
				});

				this.bioWin.setTitle(o.Name + " Bio");
				this.detailPanel.show();
				// Move focus
				//this.detailPanel.focus();
		        this.bioWin.show(this);
				
			}).createDelegate(this),
			failure: function () {alert("Bio loading failed.")},
			scope: this,
			params: {
				'id': id
			}
		});

	}
}

MapObject.app.vc.auth = {
	signupTemplate: null,
	
	/**
	* Storage for the "Signup" window object
	* @private
	* @type {Ext.Window}
	*/
	signupWin: null,
	/**
	* Storage for the "Login" window object
	* @private
	* @type {Ext.Window}
	*/
	loginWin: null,

	/**
	* Storage for the active window object
	* @private
	* @type {Ext.Window}
	*/
	activeWin: null,
	
	/**
	* Storage for the map object
	* @private
	* @type {MapObject.app.vc.map}
	*/
	map: null,
	
	/*
	* Show bio popup for a proffesional with a given id
	*/
	showForm: function(action) {
		// Clear errors
		var elError = Ext.get(action + 'Error');
		elError.dom.innerHTML = '';
		elError.hide();

		if (action ==  "signup") {
			// Content panels
			this.signupPanel = Ext.get('signupPanel');

			// create the window on the first click and reuse on subsequent clicks
			if(!this.signupWin){
				this.signupWin = new Ext.Window({
					el:'signupWin',
					layout:'fit',
					autoScroll: true,
					width:'auto',
					height:'auto',
					closeAction:'hide',
					plain: true,
					modal: true,
	                resizable: false,
                
					contentEl: 'signupPanel',

					buttons: [
					{
						text:'Submit',
						type: 'submit',
						handler: this.submit.createDelegate(this)
                	},
					{
						text: 'Close',
						handler: (function(){
							this.signupWin.hide();
						}).createDelegate(this)
					}]
				});

				// Focus first element
				this.signupWin.addListener("show", function(){
					// Focus first element
					Ext.get('signup-username').focus();
				}, this, {delay:100});

				// Add 'Submit' event handler
				Ext.get('signupForm').on('keydown', function(e) {
					if (e.getKey() == Ext.EventObject.ENTER) {
						this.submit();
					}
				}, this);

			}
			this.activeWin = this.signupWin; 
		}
		// Login
		else {

			// Content panels
			this.loginPanel = Ext.get('loginPanel');

			// create the window on the first click and reuse on subsequent clicks
			if(!this.loginWin){
				this.loginWin = new Ext.Window({
					el:'loginWin',
					layout:'fit',
					autoScroll: true,
					width:'auto',
					height:'auto',
					closeAction:'hide',
					plain: true,
					modal: true,
	                resizable: false,
                
					contentEl: 'loginPanel',

					buttons: [
					{
						text:'Submit',
						type: 'submit',
						handler: this.submit.createDelegate(this)
                	},
					{
						text: 'Close',
						handler: (function(){
							this.loginWin.hide();
						}).createDelegate(this)
					}]
				});

				this.loginWin.addListener("show", function(){
					// Focus first element
					Ext.get('login-username').focus();
				}, this, {delay:100});


				// Add 'Submit' event handler
				Ext.get('loginForm').on('keydown', function(e) {
					if (e.getKey() == Ext.EventObject.ENTER) {
						this.submit();
					}
				}, this);

			}
			this.activeWin = this.loginWin; 
		}
		this.activeWin.action = action;
		this.activeWin.show();

	},

	submit: function() {
		
		var action = this.activeWin.action;

		var params = {};
		if (action ==  "signup") {
			params = Ext.Ajax.serializeForm('signupForm');
		}
		// login
		else {
			params = Ext.Ajax.serializeForm('loginForm');
		}

		//Make ajax call and get bio informatiom
		Ext.Ajax.request({
			url: 'service/auth.php',
			params: {
				'action': action,
				'params': params
			},
			scope: this,
			success: (function(response, options) {

	            o = Ext.util.JSON.decode(response.responseText);
				
				/*

				// Details for lease type
				this.signupTemplate.overwrite(this.signupPanel, {
					Name: o.Name,
					Title: o.Title,
					Blog: ((o.Blog == '') ? '' : ('<a href="' + o.Blog + '" target="_blank">Blog</a>')),
					Bio: o.Bio
				});
				this.signupWin.setTitle(o.Name + " Bio");
				*/
				
				var elError = Ext.get(options.params.action + 'Error');
				// Check for errors
				if (o.errors.length > 0) {
					elError.dom.innerHTML = o.errors.join("<br/>") ;
					elError.show();
				}
				// Sucesfull
				else {
					elError.hide();

					// Hide register panel - remove it from DOM
					var elRegister = Ext.get('register');
					elRegister.setVisibilityMode(Ext.Element.DISPLAY);

					var elWelcome = Ext.get('welcome');
					elWelcome.setVisibilityMode(Ext.Element.DISPLAY);

					if (options.params.action == 'signup') {
						// Show thank you message
						elRegister.setVisible(true);
						elWelcome.setVisible(false);

						// Show Thank-you window
				        Ext.MessageBox.alert('Submission Thank You', 'Thanks for registering! Please check your email for an account authentication, and click on the embedded link to head back here and get going with the service.  If you encounter any problems, send an email to <a href="mailto:support@punctuative.com">support@punctuative.com</a>.');

					}
					// Sign in
					else {
						Ext.get('userName').dom.innerHTML = o.Name;

						//elWelcome.show();
						elWelcome.setVisible(true);

						//elRegister.hide();
						elRegister.setVisible(false);

						// Reload data
						this.reloadData();

					} // else
					// Hide popup
					this.activeWin.hide();
				}

				/*
				if (options.params.action == "signup") {
					this.signupPanel.show();
					this.signupWin.show(this);
				}
				// Login
				else {
					this.loginPanel.show();
					this.loginWin.show(this);
				}
				*/
				

			}).createDelegate(this),
			failure: function () {
				this.activeWin.hide();
				alert("Authentication processing failed. Please try again.")
			}
		});
	},

	logout: function() {
		
		//Make ajax call to log out
		Ext.Ajax.request({
			url: 'service/logout.php',
			params: {
				'action': 'logout'
			},
			scope: this,
			success: (function(response, options) {

				var elWelcome = Ext.get('welcome');
				elWelcome.setVisibilityMode(Ext.Element.DISPLAY);
				//elWelcome.hide();
				elWelcome.setVisible(false);

				// Show register panel - remove it from DOM
				var elRegister = Ext.get('register');
				if (elRegister) {
					elRegister.setVisibilityMode(Ext.Element.DISPLAY);
					//elRegister.show();
					elRegister.setVisible(true);
				}

				// Reload data
				this.reloadData();

			}).createDelegate(this),
			failure: function () {
				this.activeWin.hide();
				alert("Log out processing failed. Please try again.")
			}
		});
	},

	reloadData: function() {
		if (this.map === null) return;

		//Remove all Records from the Store and fires the clear event.
		this.map.ds.removeAll();
        // Invoke search
        this.map.ds.load();
	}


}


// Static utilities
MapObject.app.vc.util = {
	/* Get parent id from child record id ("12_334").
	*/
	getParentID: function(id) {
		return id.split("_")[0];
	}

}
