// vc_id = "$Id: region.js 13169 2010-11-22 19:07:29Z jgiven $"
// This library is provided to aid in the retrieval and display
// of geo regions.
// @author Robert D. Rice

// Constructor
function RegionService( server, token ) {
    // attributes
    // StateChangeListener objects.
    this.listeners = new Array( );
    this.name = "region";
    this.state = STATE_CHANGE_STATE_UNINITIALIZED;
    this.status = STATE_CHANGE_STATUS_OK;
   
    this.server = server;
    this.token = token;
    this.fix = null;
    this.query = null;
    this.error = null;
    this.count = 0;
    this.neighborhood = "maponics";
    
    // methods
    this.loadRegion = RegionServiceLoadRegion;
    this.loadRegionSingle = RegionServiceLoadRegionSingle;
    this.loadRegionChained = RegionServiceLoadRegionChained;
    this.loadRegionGeneric = RegionServiceLoadRegionGeneric;
    this.loadRegionCallbackSuccess = RegionServiceLoadRegionCallbackSuccess;
    this.loadRegionCallbackFailure = RegionServiceLoadRegionCallbackFailure;
    this.authString = RegionServiceAuthString;
    this.setFix = RegionServiceSetFix;
    this.getFix = RegionServiceGetFix;
}
RegionService.prototype = new StateChangeSupport( );

// regional service
// set the fix
// @param fix object, drives the region
function RegionServiceSetFix( fix ) {
    this.fix = fix;
}

// regional service
// get the fix
// @return fix object, drives the region
function RegionServiceGetFix( ) {
    return this.fix;
}

// regional service
// load a region
// this method picks the preferred load technique
function RegionServiceLoadRegion( ) {
    this.loadRegionSingle( );
}

// regional service
// load a region
// this method is general
// @param resource
// @param fields
function RegionServiceLoadRegionGeneric( resource, fields  ) {
    if ( this.fix ) {
	this.setState( STATE_CHANGE_STATE_LOADING );
	this.count++;

	var query = this.server + "/GetByGeometry.aspx";
	query += "?fields=" + fields;
	query += "&returnGeoType=1";
	query += "&inclusionGeometries=POINT(" + this.fix.earth.x + " " + this.fix.earth.y + ")";
	query += "&dataSource=" + resource;
	//query += this.authString( );
	this.query = query;
	
	var rs = this;
	Dmp.Util.getJson( query, 
			  function( json ) { rs.loadRegionCallbackSuccess( json ); }, 
			  function( err ) { rs.loadRegionCallbackFailure( err ); } );
    }
}

// regional service
// load a region
// this method will query a single dataset
function RegionServiceLoadRegionSingle(  ) {

    if ( this.fix ) {
	var fields = "";
	var resource = "";
 	switch ( this.fix.scheme ) {
 	case LOCATION_FIX_SCHEME.ZIP:
 	    fields = "STATEABV,COUNTYNAME,POSTCODE";
	    resource = "MY_FOLDER/ZIPAREA";
 	    break;
 	case LOCATION_FIX_SCHEME.CITY:
            fields = "MASTERKEY,STATEABV,CITYNAME,CityMaster(XMIN,XMAX,YMIN,YMAX)";
	    resource = "DMP_LICENSE/CITYAREA";
            break;
 	case LOCATION_FIX_SCHEME.COUNTY:
            fields = "COUNTYNAME,FIPS,GEOMETRY";
            resource = "MY_FOLDER/COUNTYAREA";
            break;
 	case LOCATION_FIX_SCHEME.STATE:
            fields = "STATEABV,GEOMETRY,STATENAME";
            resource = "MY_FOLDER/STATEAREA";
            break;
 	case LOCATION_FIX_SCHEME.NEIGHBORHOOD:
		fields = "NEIGHBORHD,NID,GEOMETRY,STATE";
		resource = "MY_FOLDER/NEIGHBORHOODAREA";
	   
            break;
 	}

	this.loadRegionGeneric( resource, fields );
    }
}

// regional service
// load a region
// this method will query a chained dataset
function RegionServiceLoadRegionChained(  ) {
    var fields = "POSTCODE,_DMP_ID,GEOMETRY,CitySpatialLink(CITYNAME,_DMP_ID,GEOMETRY),CountySpatialLink(COUNTYNAME,_DMP_ID,GEOMETRY),StateSpatialLink(NAME,STATEABV,_DMP_ID,GEOMETRY),NEIGHBORSPATIALLINK(NEIGHBORHD,_DMP_ID,GEOMETRY)";
    var resource = "MY_FOLDER/ZipArea";
    
    this.loadRegionGeneric( resource, fields );
}

// regional service
// load a region callback success
// @param json
function RegionServiceLoadRegionCallbackSuccess( json ) {
    this.setState( STATE_CHANGE_STATE_LOADED );
    if ( json.Response.Results.totalRecords > 0 ) {
	var records = json.Response.Results.RecordSet;
	var match = false;
	if ( !records ) {
	    records = [ json.Response.Results ];
	    records[0].Resource = records[0].datasource;
	}

	//Determine which of the records coming from ParcelStream has the boundary for the 
	//neighborhood that we are searching for. This is only an issue when there is more
	//than one record.

        var hood = unescape(getUrlVars()['hood']);
	var data = null;
	var recordNum = 0;
	var totalRecords = records[0].totalRecords;
	for(var recordCnt=0; recordCnt<totalRecords; recordCnt++) {
	    data = records[0].Data.Row[recordCnt];
	    if(hood && data && hood == data.NEIGHBORHD) {
	        recordNum = recordCnt;
	        break;
	    }
        }

	if(!data) data = records[0].Data.Row;

	var resource = records[0].Resource.toUpperCase( );

	var scheme = false;
	var field = null;
	if ( resource.toUpperCase() == "MY_FOLDER/ZIPAREA" ) { 
	    this.fix.zip = data.POSTCODE;
	    field = "POSTCODE:" + data.POSTCODE;
	    if ( this.fix.scheme == LOCATION_FIX_SCHEME.ZIP ) { scheme = true; }
	} else if ( resource.toUpperCase() == "DMP_LICENSE/CITYAREA" ) {
	    this.fix.city = data.CITYNAME;
	    field = "MASTERKEY:" + data.MASTERKEY;
	    if ( this.fix.scheme == LOCATION_FIX_SCHEME.CITY ) { scheme = true; }
	} else if ( resource.toUpperCase() == "MY_FOLDER/COUNTYAREA" ) {
	    this.fix.county = data.COUNTYNAME;
	    field = "FIPS:" + data.FIPS;
	    if ( this.fix.scheme == LOCATION_FIX_SCHEME.COUNTY ) { scheme = true; }
	} else if ( resource.toUpperCase() == "MY_FOLDER/STATEAREA" ) {
	    this.fix.state = data.STATENAME;
	    field = "STATEABV:" + data.STATEABV;
	    if ( this.fix.scheme == LOCATION_FIX_SCHEME.STATE ) { scheme = true; }
	} else if ( resource.toUpperCase() == "MY_FOLDER/NEIGHBORHOODAREA" ) {
	    this.fix.neighborhood = data.NEIGHBORHD;
	    field = "NID:" + data.NID;
	    if ( this.fix.scheme == LOCATION_FIX_SCHEME.NEIGHBORHOOD ) { scheme = true; }
	} else {}

	if ( scheme ) {
	    match = true;
	    this.fix.id = resource + ":" + field;
	    if ( data._DMP_WARNING_ && data._DMP_WARNING_ == "Reduced to Point" ) {
		this.fix.bounds = null;
		// region definition reduced to a point
		// could set status with custom, 400+ error codes
		this.error = data._DMP_WARNING_;
		this.setStatus( STATE_CHANGE_STATUS_ERROR );
	    } else {
		this.fix.bounds = data.GEOMETRY;
		this.setStatus( STATE_CHANGE_STATUS_OK );
	    }
	}

	if ( !match ) {
	    // didn't find the region scheme requested
	    // could set status with custom, 400+ error codes
	    this.error = "no scheme matches found";
	    this.setStatus( STATE_CHANGE_STATUS_ERROR );
	}
    } else {
	// no region matches found
	// could set status with custom, 400+ error codes
	this.error = "no region matches found";
	this.setStatus( STATE_CHANGE_STATUS_ERROR );
    }
    this.setState( STATE_CHANGE_STATE_COMPLETE );
}

// regional service
// load a region callback failure
// @param error
function RegionServiceLoadRegionCallbackFailure( err ) {
    this.error = err.Response.Error.message;
    // various error messages
    this.setStatus( STATE_CHANGE_STATUS_ERROR );
    this.setState( STATE_CHANGE_STATE_COMPLETE );
}

// get the auth string to append to the url
function RegionServiceAuthString( ) {
    //return "&DMP_CANDY=" + this.token;
    return "";
}

//Get URL parameters
function getUrlVars() {

  // var mlsLn = getUrlVars()['ln'];  //example usage
   var map = {};
   var parts = window.location.search.replace(/[?&]+([^=&]+)(=[^&]*)?/gi, function(m,key,value) {
   map[key] = (value === undefined) ? true : value.substring(1); });
   return map;
}

var mlsLn = getUrlVars()['ln'];


