function StateMachine() {

  //member variables
  this.path;
  this.base_city_id;
  this.base_zip_code_id;
  this.base_location_type;
  this.get_data;
  this.limit_cities = Array();
  this.limit_cities_data = Array();
  this.limit_neighborhoods = Array();
  this.limit_neighborhoods_data = Array();
  this.property_amenities = Array();
  this.unit_amenities = Array();
  this.amenities_data = Array();
  this.total_properties;
  this.last_page;
  this.has_next_page;
  this.has_prev_page;
  this.port;
  this.is_authenticated;
  this.static_url;

  //Set functions declaration
  this.set_path = set_path;
  this.set_port = set_port;
  this.set_get_data = set_get_data;
  this.set_base_city_id = set_base_city_id;
  this.set_base_zip_code_id = set_base_zip_code_id;
  this.set_base_location_type = set_base_location_type;
  this.set_search_radius = set_search_radius;
  this.set_min_rent = set_min_rent;
  this.set_max_rent = set_max_rent;
  this.set_min_beds = set_min_beds;
  this.set_max_beds = set_max_beds; 
  this.set_bathrooms = set_bathrooms;
  this.set_max_square_feet = set_max_square_feet;
  this.set_min_square_feet = set_min_square_feet;
  this.set_is_condo = set_is_condo;
  this.set_is_house = set_is_house;
  this.set_is_furnished = set_is_furnished;
  this.set_is_short_term = set_is_short_term;
  this.set_is_senior = set_is_senior;
  this.set_is_corporate = set_is_corporate;
  this.set_page_num = set_page_num;
  this.set_last_page = set_last_page;
  this.set_total_properties = set_total_properties;
  this.set_has_next_page = set_has_next_page;
  this.set_has_prev_page = set_has_prev_page;
  this.set_allow_cats = set_allow_cats;
  this.set_allow_small_dogs = set_allow_small_dogs;
  this.set_allow_large_dogs = set_allow_large_dogs;
  this.set_sort_method = set_sort_method;
  this.set_is_authenticated = set_is_authenticated;
  this.clear_bedrooms = clear_bedrooms;
  this.set_static_url = set_static_url;

  //Amenities Functions
  this.clear_amenities = clear_amenities;
  this.add_property_amenity = add_property_amenity;
  this.add_unit_amenity = add_unit_amenity;
  this.set_amenities_data = set_amenities_data;
  this.get_amenities_data = get_amenities_data;
  this.get_property_amenities = get_property_amenities;
  this.get_unit_amenities = get_unit_amenities;
  this.remove_amenity = remove_amenity;
  this.remove_property_amenity = remove_property_amenity;
  this.remove_unit_amenity = remove_unit_amenity;
 
  //Limit neighborhoods functions
  this.clear_limit_neighborhoods = clear_limit_neighborhoods;
  this.add_limit_neighborhood = add_limit_neighborhood;
  this.remove_limit_neighborhood = remove_limit_neighborhood;
  this.set_limit_neighborhoods_data = set_limit_neighborhoods_data

  //Limit city set functions
  this.clear_limit_cities = clear_limit_cities;
  this.add_limit_city = add_limit_city;
  this.remove_limit_city = remove_limit_city;
  this.set_limit_cities_data = set_limit_cities_data;
  this.add_limit_city_base = add_limit_city_base;
  this.remove_limit_city_base = remove_limit_city_base;

  //Limit zip code stuff
  this.limit_to_base_zip_code = limit_to_base_zip_code;
  this.clear_limit_zip_code = clear_limit_zip_code;

  //Get Functions declaration
  this.get_last_page = get_last_page;
  this.get_total_properties = get_total_properties;
  this.get_limit_cities = get_limit_cities;
  this.get_limit_cities_data = get_limit_cities_data;
  this.get_limit_neighborhoods = get_limit_neighborhoods;
  this.get_limit_neighborhoods_data = get_limit_neighborhoods_data;
  this.get_url = get_url;
  this.get_get_data = get_get_data;
  this.get_has_next_page = get_has_next_page;
  this.get_has_prev_page = get_has_prev_page;
  this.get_default_url = get_default_url;
  this.get_base_location_type = get_base_location_type;
  this.get_perma_link = get_perma_link;
  this.get_xml_link = get_xml_link;
  this.get_rss_link = get_rss_link;
  this.get_is_authenticated = get_is_authenticated;
  this.get_base_url = get_base_url;
  this.get_static_url = get_static_url;
} 

//Set function implimentation
function set_port(_port) {
  if (_port == "80") {
    this.port = ""
  } else {
    this.port = ":" + _port;
  }
}

function set_static_url(_static_url) {
  this.static_url = _static_url;
}

function set_is_authenticated(_is_authenticated) {
  this.is_authenticated = _is_authenticated;
}

function get_default_url() {
  return 'http://' + window.location.hostname + this.port + this.path;
}

function set_sort_method(_sort_method) {
  this.get_data["sort_method"]  = _sort_method;
}

function set_has_next_page(_has_next_page) {
  if(_has_next_page.toLowerCase() == "true") { _has_next_page = true; } else { _has_next_page = false; }
  this.has_next_page = _has_next_page;
}

function set_has_prev_page(_has_prev_page) {
  if(_has_prev_page.toLowerCase() == "true") { _has_prev_page = true; } else { _has_prev_page = false; }
  this.has_prev_page = _has_prev_page;
}

function set_page_num(_page_num) {
  this.get_data["page_num"]  = _page_num;
}

function set_last_page(_last_page) {
  this.last_page = _last_page;
}

function set_total_properties(_total_properties) {
  this.total_properties = _total_properties;
}

function clear_amenities() {
  this.property_amenities = Array();
  this.unit_amenities = Array();
}

function add_property_amenity(_amenity_id) {
  this.property_amenities.push(_amenity_id);
}

function add_unit_amenity(_amenity_id) {
  this.unit_amenities.push(_amenity_id);
}

function set_allow_cats(_allow_cats) {
  this.get_data["allow_cats"] = _allow_cats;
}

function set_allow_small_dogs(_allow_small_dogs) {
  this.get_data["allow_small_dogs"] = _allow_small_dogs;
}

function set_allow_large_dogs(_allow_large_dogs) {
  this.get_data["allow_large_dogs"] = _allow_large_dogs;
}

function set_amenities_data(_amenities_data) {
  this.amenities_data = _amenities_data;
}

function set_is_furnished(_is_furnished) {
  this.get_data["is_furnished"] = _is_furnished;
}

function set_is_short_term(_is_short_term) {
  this.get_data["is_short_term"] = _is_short_term;
}

function set_is_senior(_is_senior) {
  this.get_data["is_senior"] = _is_senior;
}

function set_is_corporate(_is_corporate) {
  this.get_data["is_corporate"] = _is_corporate;
}

function set_is_condo(_is_condo) {
  this.get_data["is_condo"] = _is_condo;
}

function set_is_house(_is_house) {
  this.get_data["is_house"] = _is_house;
}

function set_max_square_feet(_max_square_feet) {
  this.get_data["max_square_feet"] = _max_square_feet; 
}

function set_min_square_feet(_min_square_feet) {
  this.get_data["min_square_feet"] = _min_square_feet;
}

function set_bathrooms(_bathrooms) {
  this.get_data["bathrooms"] = _bathrooms;
}

function set_min_beds(_min_beds) {
  this.get_data["min_beds"] = _min_beds;
}

function set_max_beds(_max_beds) {
  this.get_data["max_beds"] = _max_beds;
}

function set_min_rent(_min_rent) {
  this.get_data["min_rent"] = _min_rent;
}
function set_max_rent(_max_rent) {
  this.get_data["max_rent"] = _max_rent;
}

function set_get_data(_get_data) {
  //This is the mother function where we do all our logic to 
  //determine how the page should be displayed.   All display logic
  //goes HERE not in the django code.
  this.get_data = _get_data;

  //Build limit cities list if we have it.
  if(typeof this.get_data['limit_cities'] != 'undefined') {
    this.limit_cities = String(this.get_data['limit_cities']).split("-");
  }

  //Build limit neighborhoods if we have it.
  if(typeof this.get_data['limit_neighborhoods'] != 'undefined') {
    this.limit_neighborhoods = String(this.get_data['limit_neighborhoods']).split("-");
  }

  //Build amenities if we have to if we have it.
  if(typeof this.get_data['property_amenities'] != 'undefined') {
    this.property_amenities = String(this.get_data['property_amenities']).split("-");
  }
  if(typeof this.get_data['unit_amenities'] != 'undefined') {
    this.unit_amenities = String(this.get_data['unit_amenities']).split("-");
  }


}

function set_path(_path) {
  this.path = _path;
}

function set_base_zip_code_id(_base_zip_code_id) {
  this.base_zip_code_id = _base_zip_code_id;
}

function set_base_city_id(_base_city_id) {
  this.base_city_id = _base_city_id;
}

function set_base_location_type(_base_location_type) {
  this.base_location_type = _base_location_type;
}

function clear_limit_cities() {
  this.limit_cities = Array();
}

function clear_limit_neighborhoods() {
  this.limit_neighborhoods = Array();
}


function add_limit_neighborhood(_neighborhood_id) {
  //we have to remove the main city from limit cities if its their
  this.remove_limit_city_base();  
  this.limit_neighborhoods.push(_neighborhood_id);
}

function add_limit_city(city_id) {
  if ((this.base_location_type == "city" || this.base_location_type == "college" || this.base_location_type == "neighborhood") && this.limit_cities.length == 0 && this.limit_neighborhoods.length == 0) {
    this.add_limit_city_base();
  }
  this.limit_cities.push(city_id);
}

function remove_limit_city_base() {
  var remove_index = -1;
  for(i=0;i<this.limit_cities.length;i++) {
    if(this.limit_cities[i] == this.base_city_id) { remove_index = i; }
  }
  if(remove_index != -1) { this.limit_cities.splice(remove_index,1); }
}

//Adds the base city id to limit cities.
function add_limit_city_base() {
  var found_base_id = false;
  for(i=0;i<this.limit_cities.length;i++) {
    if(parseInt(this.limit_cities[i]) == parseInt(this.base_city_id)) { found_base_id = true; }
  }
  if(found_base_id == false) { this.limit_cities.push(this.base_city_id) };
}

function remove_limit_neighborhood(_neighborhood_id) {
  var remove_index = -1;
  for(i=0;i<this.limit_neighborhoods.length;i++) {
    if(this.limit_neighborhoods[i] == _neighborhood_id) { remove_index = i; }
  }
  if(remove_index != -1) { this.limit_neighborhoods.splice(remove_index,1); }
  if((this.limit_cities.length > 0 || this.get_data["search_radius"] == -2) && this.limit_neighborhoods.length == 0) { this.add_limit_city_base(); }
}
function remove_amenity(amenity_id) {
  this.remove_property_amenity(amenity_id);
  this.remove_unit_amenity(amenity_id);
  return 0;
}

function remove_property_amenity(amenity_id) {
  var remove_index = -1;
  for(i=0;i<this.property_amenities.length;i++) {
    if(this.property_amenities[i] == amenity_id) { remove_index = i; }
  }
  if(remove_index != -1) { this.property_amenities.splice(remove_index,1); }
}

function remove_unit_amenity(amenity_id) {
  var remove_index = -1;
  for(i=0;i<this.unit_amenities.length;i++) {
    if(this.unit_amenities[i] == amenity_id) { remove_index = i; }
  }
  if(remove_index != -1) { this.unit_amenities.splice(remove_index,1); }
}


function remove_limit_city(city_id) {
  var remove_index = -1;
  for(i=0;i<this.limit_cities.length;i++) {
    if(this.limit_cities[i] == city_id) { remove_index = i; }
  }
  if(remove_index != -1) { this.limit_cities.splice(remove_index,1); }
  if(this.limit_cities.length == 1 && this.limit_cities[0] == this.base_city_id && this.get_data["search_radius"] != -2) { this.limit_cities = Array(); }
}

function set_limit_neighborhoods_data(_limit_neighborhoods_data) {
  this.limit_neighborhoods_data = _limit_neighborhoods_data;
}

function set_limit_cities_data(_limit_cities_data) {
  this.limit_cities_data = _limit_cities_data;
}

function set_search_radius(_search_radius) {
  this.get_data['search_radius'] = _search_radius;
}

function limit_to_base_zip_code() {
  this.get_data["limit_zip_codes"] = this.base_zip_code_id;
}

function clear_limit_zip_code() {
  delete this.get_data["limit_zip_codes"];
}

function clear_bedrooms() {
  delete this.get_data["min_beds"];
  delete this.get_data["max_beds"];
}

//Get funtion implimentations
function get_has_next_page() {
  return this.has_next_page;
}

function get_has_prev_page() {
  return this.has_prev_page;
}

function get_last_page() {
  return this.last_page;
}

function get_total_properties() {
  return this.total_properties;
}

function get_property_amenities() {
  return this.property_amenities;
}

function get_unit_amenities() {
  return this.unit_amenities;
}

function get_amenities_data() {
  return this.amenities_data;
}

function get_get_data() {
  return this.get_data;
}

function get_base_location_type() {
  return this.base_location_type;
}

function get_limit_cities() {
  return this.limit_cities;
}

function get_limit_cities_data() {
  return this.limit_cities_data;
}

function get_limit_neighborhoods() {
  return this.limit_neighborhoods;
}

function get_limit_neighborhoods_data() {
  return this.limit_neighborhoods_data;
}

function get_is_authenticated() {
  return this.is_authenticated;
}

function get_static_url() {
  return this.static_url;
}

//This is the RESET url
function get_default_url() {
  return 'http://' + window.location.hostname + this.port + this.path;
}

//This is just the hostname with the port (no directories)
function get_base_url() {
  return 'http://' + window.location.hostname + this.port;
}

function get_perma_link() {
  return 'http://' + window.location.hostname + this.port + this.path + this.get_url();
}

function get_xml_link() {
  return 'http://' + window.location.hostname + this.port + '/properties_list.xml' + this.get_url();  
}

function get_rss_link() {
  return 'http://' + window.location.hostname + this.port + '/feeds/properties/' + this.get_url();
}

function get_url() {
  if(this.limit_cities.length == 0) { 
    if (typeof this.get_data['limit_cities'] != 'undefined') {
      delete this.get_data['limit_cities'];
    }
  } else {
    this.get_data['limit_cities'] = this.limit_cities.join("-");
  }  

  if(this.limit_neighborhoods.length == 0) {
    if (typeof this.get_data['limit_neighborhoods'] != 'undefined') {
      delete this.get_data['limit_neighborhoods'];
    }
  } else {
    this.get_data['limit_neighborhoods'] = this.limit_neighborhoods.join("-");
  }

  if(this.property_amenities.length == 0) {
    if (typeof this.get_data['property_amenities'] != 'undefined') {
      delete this.get_data['property_amenities'];
    }
  } else {
    this.get_data['property_amenities'] = this.property_amenities.join("-");
  }

  if(this.unit_amenities.length == 0) {
    if (typeof this.get_data['unit_amenities'] != 'undefined') {
      delete this.get_data['unit_amenities'];
    }
  } else {
    this.get_data['unit_amenities'] = this.unit_amenities.join("-");
  }


  var url = "";
  var count = 0;
  for(var k in this.get_data) {
    if(count == 0) { url = url + "?" } else { url = url + "&" }
    url = url + k + "=" + this.get_data[k];
    count = count + 1;
  }
  return url;
}
