CCC.namespace("rf");

CCC.rf.tower_data_loc       = 'towers.json';
CCC.rf.map                  = null;
CCC.rf.geocoder             = null;
CCC.rf.projection           = null;
CCC.rf.tower_data           = {};
CCC.rf.zoom                 = 9;
CCC.rf.icons                = {};
CCC.rf.markers              = {};
CCC.rf.customers            = {};
CCC.rf.max_radius           = 0;
CCC.rf.mult_addr_dlg        = null;
CCC.rf.lookup_tab           = null;
CCC.rf.center_map           = null;
CCC.rf.location_counter     = 0;
CCC.rf.geocode_status_codes = {
  200 : "Success.",
  500 : "A geocoding request could not be successfully processed, yet the "+
        "exact reason for the failure is not known.",
  601 : "The addressparameter was either missing or had no value.",
  602 : "No corresponding geographic location could be found for the "+
        "specified address. This may be due to the fact that the address "+
        "is relatively new; it was changed recently for 911 purposes (in "+
        "this case try the old address); it may be "+
        "incorrect; or you may have left off the zip code. ",
  603 : "The geocode for the given address cannot be returned due to legal "+
        "or contractual reasons.",
  610 : "The given key is either invalid or does not match the domain for "+
        "which it was given."
};

CCC.rf.init = function() {
  if (GBrowserIsCompatible()) {
    CCC.rf.projection = G_NORMAL_MAP.getProjection();

    var elem = CCC.util.dom.get_element('map');
    //CCC.rf.map = new GMap2(elem,{draggableCursor:"crosshair"});
    CCC.rf.map = new GMap2(elem);

    CCC.rf.map.addControl(new GScaleControl());
    CCC.rf.map.addControl(new GLargeMapControl());
    CCC.rf.map.addControl(new GMapTypeControl());
    CCC.rf.map.setCenter(new GLatLng(37.97,-87.55),CCC.rf.zoom);

    CCC.rf.center_map = function (p) {
      //CCC.rf.map.setCenter(p);
      CCC.rf.map.panTo(p); 
    };

    var base_icon = new GIcon();
    base_icon.shadow = "images/marker-shadow.png";
    base_icon.image = "images/red-marker.png";
    base_icon.iconSize = new GSize(20,34);
    base_icon.shadowSize = new GSize(37,34);
    base_icon.iconAnchor = new GPoint(9,33);
    base_icon.infoWindowAnchor = new GPoint(9,2);

    CCC.rf.icons.red_marker = new GIcon(base_icon);

    CCC.rf.icons.blue_marker = new GIcon(base_icon);
    CCC.rf.icons.blue_marker.image = "images/blue-marker.png";

    CCC.rf.icons.green_marker = new GIcon(base_icon);
    CCC.rf.icons.green_marker.image = "images/green-marker.png";

    CCC.rf.icons.yellow_marker = new GIcon(base_icon);
    CCC.rf.icons.yellow_marker.image = "images/yellow-marker.png";

    base_icon = new GIcon();
    base_icon.shadow = "images/flag-shadow.png";
    base_icon.image = "images/red-flag.png";
    base_icon.iconSize = new GSize(16,29);
    base_icon.shadowSize = new GSize(27,28);
    base_icon.iconAnchor = new GPoint(2,28);
    base_icon.infoWindowAnchor = new GPoint(9,2);

    CCC.rf.icons.red_flag = new GIcon(base_icon);

    CCC.rf.icons.blue_flag = new GIcon(base_icon);
    CCC.rf.icons.blue_flag.image = "images/blue-flag.png";

    CCC.rf.icons.green_flag = new GIcon(base_icon);
    CCC.rf.icons.green_flag.image = "images/green-flag.png";

    CCC.rf.icons.yellow_flag = new GIcon(base_icon);
    CCC.rf.icons.yellow_flag.image = "images/yellow-flag.png";

    CCC.rf.icons['default'] = G_DEFAULT_ICON;
  } else {
    var dialog = CCC.util.html.create_simple_dialog_panel({
      body   : "Your browser appears to be incompatible with this application.",
      icon   : YAHOO.widget.SimpleDialog.ICON_WARN
    });
  }
};

CCC.rf.create_marker = function(point, text, params) {
  params = (params === null) ? {} : params;
  params.icon = (params.icon) ? params.icon : CCC.rf.icons["default"];
  params.importance = (params.importance) ? params.importance : 1;

  //---------------------------------------------------------------------------
  // Only allow one marker per point to be placed on the map
  //---------------------------------------------------------------------------
  if (CCC.rf.markers[point]) {
    //GEvent.trigger(CCC.rf.markers[point],"click");
    return;
  }

  CCC.rf.markers[point] = new GMarker(point,{ 
    icon : params.icon, zIndexProcess : CCC.rf.set_marker_zindex
  });
  CCC.rf.markers[point].importance = params.importance;

  CCC.rf.map.addOverlay(CCC.rf.markers[point]);

  if (params.address !== null) {
    CCC.rf.markers[point].title = params.address;
  }

  GEvent.addListener(CCC.rf.markers[point], "click", function () {
    CCC.rf.markers[point].openInfoWindowHtml(text);
    CCC.rf.center_map(point);
  });

  if (params.center !== null && params.center) {
    CCC.rf.center_map(point);
  }

  if (params.open_info !== null && params.open_info) {
    CCC.rf.markers[point].openInfoWindowHtml(text);
  }

  return CCC.rf.markers[point];
};

CCC.rf.set_marker_zindex = function(m,b) {
  return GOverlay.getZIndex(m.getPoint().lat()) + m.importance * 1000000;
};

CCC.rf.format_address = function(e) {
  var abbr = {
    av         : "ave",
    avenue     : "ave",
    circle     : "cir",
    court      : "ct",
    drive      : "dr",
    east       : "e",
    expressway : "expy",
    highway    : "hwy",
    junction   : "jct",
    lane       : "ln",
    north      : "n",
    parkway    : "pkwy",
    point      : "pt",
    road       : "rd",
    route      : "rte",
    south      : "s",
    square     : "sq",
    street     : "st",
    terrace    : "ter",
    trail      : "trl",
    turnpike   : "tpke",
    west       : "w"
  };

  e = e.toLowerCase();
  e = e.replace(/[.\']/g, "");
  e = e.replace(/\W/g, " ");
  e = e.replace(/\s{2,}/g, " ");
  var arr = e.split(' ');
  for (var i=0; i<arr.length; i++) {
    if (abbr[arr[i]]) {
      arr[i] = abbr[arr[i]];
    }
  }
  e = arr.join(' ');

  return(e);
}

CCC.rf.find_address = function(form) {
  var street = CCC.rf.format_address(form.street.value);
  var zip = form.zip.value;
  if (form.plus4.value.length > 0) {
    zip += "-"+form.plus4.value;
  }
  var address = [
    street,
    form.city.value.toLowerCase(),
    form.state.value.toLowerCase(),
    zip
  ].join(', ');

  if (!CCC.rf.geocoder) {
    CCC.rf.geocoder = new GClientGeocoder();
  }

  if (CCC.rf.geocoder) {
    CCC.rf.geocoder.getLocations(
      address,
      function(result) {
        if (result.Status.code != G_GEO_SUCCESS) {
          var dialog = CCC.util.html.create_simple_dialog_panel({
            body   : CCC.rf.geocode_status_codes[result.Status.code]+
                     " ("+result.Status.code+")",
            icon   : YAHOO.widget.SimpleDialog.ICON_WARN
          });
        } else {
          var len = result.Placemark.length;
          if (len > 1) {
            var a = '';
            for (var i=0; i<len; i++) {
              a += "<input type=\"radio\" name=\"mult-addrs\" value=\""+
                    result.Placemark[i].Point.coordinates[1]+"|"+
                    result.Placemark[i].Point.coordinates[0]+"|"+
                    result.Placemark[i].address+
                   "\" /> "+result.Placemark[i].address+"<br />";
            }
            CCC.util.dom.get_element('multiple-addrs-info').innerHTML = a;
            CCC.rf.display_multiple_addrs_dlg();
          } else {
            var point = new GLatLng(
              result.Placemark[0].Point.coordinates[1],
              result.Placemark[0].Point.coordinates[0]
            );
            CCC.rf.mark_customer_address(result.Placemark[0].address,point);       
          }
        }
      }
    );
  }
};

CCC.rf.find_by_click = function(marker, point) {
  if (point != null) {
    var elem = CCC.util.dom.get_element('slct_name').value;
    var name = elem;
    if (elem.length <= 0) {
      CCC.rf.location_counter++;
      name = "Location "+CCC.rf.location_counter;
    }
    CCC.rf.mark_customer_address(name,point);       
  }
}

CCC.rf.find_coordinates = function(form) {
  if (form.fc_lng.value.length > 0 && form.fc_lat.value.length > 0) {
    var point = new GLatLng(
      form.fc_lat.value,
      form.fc_lng.value
    );
    var name = form.fc_name.value;
    if (form.fc_name.value.length <= 0) {
      CCC.rf.location_counter++;
      name = "Location "+CCC.rf.location_counter;
    }
    CCC.rf.mark_customer_address(name,point);       
  }
};

CCC.rf.display_multiple_addrs_dlg = function(obj) {
  obj = (obj == null) ? {} : obj;

  if (CCC.rf.mult_addr_dlg) {
    CCC.rf.mult_addr_dlg.show();
  } else {
    CCC.rf.mult_addr_dlg = new YAHOO.widget.Dialog(
      "multiple-addrs-dlg", 
      {
        fixedcenter : true,
        width       : "500px",
        modal       : true,
        draggable   : true,
        visible     : true,
        postmethod  : "none",
        close       : false
      }
    );
    CCC.util.dom.get_element('multiple-addrs-dlg').style.display = 'block';
    CCC.rf.mult_addr_dlg.render();
  }

};

CCC.rf.select_address = function() {
  CCC.rf.mult_addr_dlg.hide();

  var arr = document.getElementsByName('mult-addrs');
  var len = arr.length;
  for (var i=0; i<len; i++) {
    if (arr[i].checked) {
      var vals = arr[i].value.split(/\s*\|\s*/);
      var point = new GLatLng(vals[0],vals[1]);

      CCC.util.dom.get_element('multiple-addrs-info').innerHTML = "";

      CCC.rf.mark_customer_address(vals[2],point);       

      return;
    }
  }

  var dialog = CCC.util.html.create_simple_dialog_panel({
    body   : "No selection was made",
    icon   : YAHOO.widget.SimpleDialog.ICON_WARN
  });
};

CCC.rf.mark_customer_address = function(address,point) {
  //-------------------------------------------------------------------
  // Only allow one marker per point to be placed on the map
  //-------------------------------------------------------------------
  if (CCC.rf.markers[point]) {
    GEvent.trigger(CCC.rf.markers[point],"click");
    return;
  }

  CCC.rf.customers[point] = {
    name                 : address,
    point                : point,
    marker               : marker,
    radius_covered       : false,
    towers_radius        : [],
    polygon_covered      : false,
    towers_polygon       : [],
    dead_polygon_covered : false,
    towers_dead_polygon  : []
  };

  CCC.rf.within_dead_polygon_coverage(point);
  //---------------------------------------------------------------------------
  // If we are in a dead zone, then there is no need to see if we are in a 
  // green zone -- there'll still be no coverage for that point.
  //---------------------------------------------------------------------------
  if (!CCC.rf.customers[point].dead_polygon_covered) {
    CCC.rf.within_polygon_coverage(point);
  }
  CCC.rf.within_radius_coverage(point);

  var elem = document.createElement('li');
  elem.id = point;
  /*
  elem.innerHTML = '<input type="checkbox" checked="checked" '+
                   'value="'+point+'" onclick="if (this.checked) '+
                   'CCC.rf.markers[this.value].show(); else '+
                   'CCC.rf.markers[this.value].hide();"> '+address;
  */
  elem.innerHTML = address;
  CCC.util.dom.get_element('addresses-ul').appendChild(elem);

  var icon = "red_flag";
  var text = "Status: Location is currently uncovered.<br />Very low probability of signal availability.";
  var rv = CCC.rf.is_customer_green(CCC.rf.customers[point]);
  if (rv == 1 || rv == 3) {
    elem.className = "covered";
    elem.style.listStyleImage = "url(images/sm-green-flag.png)";
    text = "Status: 80% or better probability of coverage.<br /> An order may be placed immediately for this location.";
    icon = "green_flag";
  } else if (rv == 2) {
    elem.className = "partial-coverage";
    text = "Status: Approximately 50% probability of coverage.<br />A test may be required to confirm signal stability.";
    elem.style.listStyleImage = "url(images/sm-yellow-flag.png)";
    icon = "yellow_flag";
  } else {
    elem.className = "not-covered";
    elem.style.listStyleImage = "url(images/sm-red-flag.png)";
    icon = "red_flag";
  }

  var marker = CCC.rf.create_marker(
    point,
    "Customer:<br />"+address+"<br />"+text+"<br />Lat, Lng: "+point.toUrlValue(6), 
    {
      center     : false, 
      open_info  : false, 
      importance : 10, 
      icon       : CCC.rf.icons[icon]
    }
  );

  YAHOO.util.Event.addListener(
    elem,
    'click',
    function () {
      GEvent.trigger(this,"click");
    },
    null,
    marker
  );

  GEvent.addListener(
    marker,
    "infowindowopen", 
    function () {
      var p = this.getPoint();
      for (var i in CCC.rf.customers[p].towers_radius) {
        CCC.rf.remove_circle(CCC.rf.customers[p].towers_radius[i]);
        //CCC.rf.remove_filled_circle(CCC.rf.customers[p].towers_radius[i]);

        CCC.rf.draw_filled_circle(CCC.rf.customers[p].towers_radius[i]);
      }
      CCC.rf.center_map(p);
    }
  );

  GEvent.addListener(
    marker,
    "infowindowclose", 
    function () {
      var p = this.getPoint();
      for (var i in CCC.rf.customers[p].towers_radius) {
        CCC.rf.remove_circle(CCC.rf.customers[p].towers_radius[i]);
        CCC.rf.remove_filled_circle(
          CCC.rf.customers[p].towers_radius[i]
        );
        CCC.rf.draw_circle(
          CCC.rf.customers[p].towers_radius[i],
          CCC.rf.customers[p].towers_radius[i].point,
          CCC.rf.customers[p].towers_radius[i].radius_point
        );
      }
    }
  );

  GEvent.trigger(marker,"click");
};

//-----------------------------------------------------------------------------
// 0 - no coverage (red)
// 1 - radius coverage, no polygon present (green)
// 2 - radius coverage, polygon present, no polygon coverage (yellow)
// 3 - raiius coverage, polygon present, polygon coverage (green);
//-----------------------------------------------------------------------------
CCC.rf.is_customer_green = function(c) {
  var good = 0;

  if (c.dead_polygon_covered) {
    return good;
  }

  for (var i in c.towers_radius) {
    if (!c.towers_radius[i].points && c.radius_covered) {
      good = 1;
      break;
    }

    if (c.towers_radius[i].points && c.polygon_covered) {
      good = 3;
    } else if (c.towers_radius[i].points && !c.polygon_covered) {
      good = 2;
    }
  }

  return good;
}

//-----------------------------------------------------------------------------
// Code taken from http://maps.forum.nu/gm_clickable_circle.html
//-----------------------------------------------------------------------------
CCC.rf.within_radius_coverage = function(p) {
  for (var i in CCC.rf.tower_data.towers) { 
    var rad_on_earth = CCC.rf.tower_data.towers[i].point.distanceFrom(
      CCC.rf.tower_data.towers[i].radius_point
    );
    var cust_distance = CCC.rf.tower_data.towers[i].point.distanceFrom(p);

    if (cust_distance < rad_on_earth) {
      CCC.rf.customers[p].towers_radius.push(CCC.rf.tower_data.towers[i]);
      CCC.rf.customers[p].radius_covered = true;
    }
  }
};

//-----------------------------------------------------------------------------
// Code taken from http://alienryderflex.com/polygon/
// via
// http://www.econym.demon.co.uk/googlemaps/inside.htm
//-----------------------------------------------------------------------------
CCC.rf.within_polygon_coverage = function(p) {
  var x  = p.lng();
  var y  = p.lat();

  var i, j = 0, k, on = false, vc;
  var klat, jlat, klng, jlng;
  for (var i in CCC.rf.tower_data.towers) { 
    if (!CCC.rf.tower_data.towers[i].init) {
      CCC.rf.init_tower_info(CCC.rf.tower_data.towers[i]);
    }

    if (!CCC.rf.tower_data.towers[i].points_loaded) {
      continue;
    }

    var pg = CCC.rf.tower_data.towers[i].filled_polygon;
    var vc = pg.getVertexCount();

    j = vc - 1;
    //var on = false;
    for (var k=0; k<vc; k++) {
      //j++;
      if (j == vc) {
        j = 0;
      }
      klat = pg.getVertex(k).lat();
      jlat = pg.getVertex(j).lat();
      klng = pg.getVertex(k).lng();
      jlng = pg.getVertex(j).lng();
      if (((klat < y) && (jlat >= y)) || ((jlat < y) && (klat >= y))) {
        if (klng + (y - klat) / (jlat - klat) * (jlng - klng) < x) {
          on = !on
          //if (on) {
          //  CCC.rf.customers[p].polygon_covered = true;
          //} else {
          //  CCC.rf.customers[p].polygon_covered = false;
          //}
        }
      }
      j = k;
      CCC.rf.customers[p].polygon_covered = on;
    }
    if (CCC.rf.customers[p].polygon_covered) {
      CCC.rf.customers[p].towers_polygon.push(
        CCC.rf.tower_data.towers[i]
      );
    }
  }
};

//-----------------------------------------------------------------------------
// Code taken from http://alienryderflex.com/polygon/
// via
// http://www.econym.demon.co.uk/googlemaps/inside.htm
//-----------------------------------------------------------------------------
CCC.rf.within_dead_polygon_coverage = function(p) {
  var x  = p.lng();
  var y  = p.lat();

  for (var i in CCC.rf.tower_data.towers) { 
    if (!CCC.rf.tower_data.towers[i].init) {
      CCC.rf.init_tower_info(CCC.rf.tower_data.towers[i]);
    }

    if (!CCC.rf.tower_data.towers[i].dead_points_loaded) {
      continue;
    }

    for (var j in CCC.rf.tower_data.towers[i].dead_points_polygons) {
      var pg = CCC.rf.tower_data.towers[i].dead_points_polygons[j];
      var vc = pg.getVertexCount();
  
      var l  = 0;
      var on = false;
      for (var k=0; k<vc; k++) {
        l++;
        if (l == vc) {
          l = 0;
        }
        var klat = pg.getVertex(k).lat();
        var llat = pg.getVertex(l).lat();
        var klng = pg.getVertex(k).lng();
        var llng = pg.getVertex(l).lng();

        if (((klat < y) && (llat >= y)) || ((llat < y) && (klat >= y))) {
          if (klng + (y - klat) / (llat - klat) * (llng - klng) < x) {
            on = !on
            if (on) {
              CCC.rf.customers[p].dead_polygon_covered = true;
            } else {
              CCC.rf.customers[p].dead_polygon_covered = false;
            }
          }
        }
      }
      //-----------------------------------------------------------------------
      // If we are in a dead zone, then there is no need to check other ones
      //-----------------------------------------------------------------------
      if (CCC.rf.customers[p].dead_polygon_covered) {
        break;
      }
    }
  }
};

//-----------------------------------------------------------------------------
// Code taken from http://www.movable-type.co.uk/scripts/LatLong.html
//-----------------------------------------------------------------------------
CCC.rf.destination_point = function(p,d) {
    var R       = 3958.75587; // Earth's mean radius in miles
    var bearing = 0 * Math.PI / 180; // For posterity.
    var lat1    = p.latRadians();
    var lng1    = p.lngRadians();

    var lat2 = Math.asin(
      Math.sin(lat1) * Math.cos(d/R) + 
      Math.cos(lat1) * Math.sin(d/R) *
      Math.cos(bearing)
    );

    if (isNaN(lat2)) {
      return null;
    }

    var lng2 = lng1 + Math.atan2(
      Math.sin(bearing) * Math.sin(d/R) * Math.cos(lat1),
      Math.cos(d/R) - Math.sin(lat1) * Math.sin(lat2)
    );

    if (isNaN(lng2)) {
      return null;
    }

    return (new GLatLng(((lat2 * 180) / Math.PI),((lng2 * 180) / Math.PI)));
};

//-----------------------------------------------------------------------------
// Code taken from http://groups.google.com/group/Google-Maps-API/         \
// browse_thread/thread/67d2a08cf0a95850/c5d34fe479827b6e?lnk=st&q=        \
// google+maps+draw+radius&rnum=5#c5d34fe479827b6e
//-----------------------------------------------------------------------------
CCC.rf.get_radius_points = function(tower,radius_point) {
  var zoom     = CCC.rf.map.getZoom();
  var center_p = CCC.rf.projection.fromLatLngToPixel(tower.point, zoom);
  var radius_p = CCC.rf.projection.fromLatLngToPixel(radius_point, zoom);
  var pts      = [];

  var radius = Math.floor(Math.sqrt(
    Math.pow((center_p.x - radius_p.x),2) + 
    Math.pow((center_p.y - radius_p.y),2)
  ));
  for (var i = 0; i < 361; i += 15) {
    var rad = i * (Math.PI/180);
    var y = center_p.y + radius * Math.sin(rad);
    var x = center_p.x + radius * Math.cos(rad);
    var p = new GPoint(x,y);
    pts.push(CCC.rf.projection.fromPixelToLatLng(p, zoom));
  }

  return(pts);
};

CCC.rf.draw_max_filled_circle = function(tower) {
  if (tower.radius === 0) {
    return;
  }

  var zoom     = CCC.rf.map.getZoom();
  var center_p = CCC.rf.projection.fromLatLngToPixel(tower.point, zoom);
  var radius_p = CCC.rf.projection.fromLatLngToPixel(
    tower.max_radius_point, zoom
  );

  if (!tower.max_circle_pts) {
    tower.max_circle_pts = CCC.rf.get_radius_points(
      tower,tower.max_radius_point
    );
  }

  if (!tower.max_filled_circle_line) {
    tower.max_filled_circle_line = new GPolygon(
      tower.max_circle_pts,
      "#AAAAAA", 2, .5, "#AAAAAA", 0.3
    );
  }

  CCC.rf.map.addOverlay(tower.max_filled_circle_line);
};

CCC.rf.draw_max_circle = function(tower) {
  if (tower.radius === 0) {
    return;
  }

  var zoom     = CCC.rf.map.getZoom();
  var center_p = CCC.rf.projection.fromLatLngToPixel(tower.point, zoom);
  var radius_p = CCC.rf.projection.fromLatLngToPixel(
    tower.max_radius_point, zoom
  );

  if (!tower.max_circle_pts) {
    tower.max_circle_pts = CCC.rf.get_radius_points(
      tower,tower.max_radius_point
    );
  }

  if (!tower.max_circle_line) {
    tower.max_circle_line = new GPolyline(tower.max_circle_pts,'#AAAAAA',2,.5);
  }

  CCC.rf.map.addOverlay(tower.max_circle_line);
};

CCC.rf.remove_max_circle = function(tower) {
  if (tower.max_circle_line) {
    CCC.rf.map.removeOverlay(tower.max_circle_line);
  }
};

CCC.rf.remove_max_filled_circle = function(tower) {
  if (tower.max_filled_circle_line) {
    CCC.rf.map.removeOverlay(tower.max_filled_circle_line);
  }
};

CCC.rf.draw_circle = function(tower,c,r) {
  var zoom     = CCC.rf.map.getZoom();
  var center_p = CCC.rf.projection.fromLatLngToPixel(tower.point, zoom);
  var radius_p = CCC.rf.projection.fromLatLngToPixel(tower.radius_point, zoom);

  if (!tower.circle_pts) {
    tower.circle_pts = CCC.rf.get_radius_points(tower,tower.radius_point);
  }

  if (!tower.circle_line) {
    tower.circle_line = new GPolyline(tower.circle_pts,'#0000FF',2,.3);
  }

  CCC.rf.map.addOverlay(tower.circle_line);
};

CCC.rf.remove_circle = function(tower) {
  CCC.rf.map.removeOverlay(tower.circle_line);
};

CCC.rf.init_tower_info = function(tower) {
  if (tower.points && !tower.points_loaded) {
    tower.points.encoded = [];
    tower.radius_fill_color = "#ECE661";
    for (var i in tower.points.raw) {
      tower.points.encoded.push(new GLatLng(
          tower.points.raw[i].latitude, tower.points.raw[i].longitude
      ));
    }
    //-------------------------------------------------------------------------
    // The first point also has to be the last or the polygon will not close.
    //-------------------------------------------------------------------------
    tower.points.encoded.push(tower.points.encoded[0]);

    tower.filled_polygon = new GPolygon(
      tower.points.encoded, 
      tower.radius_border_color, 
      2, 
      .7, 
      tower.polygon_fill_color, 
      .7
    );

    tower.points_loaded = true;
  }

  if (tower.dead_points && !tower.dead_points_loaded) {
    tower.dead_points_polygons = [];
    for (var i in tower.dead_points) {
      tower.dead_points[i].encoded  = [];
      for (var j in tower.dead_points[i].raw) {
        tower.dead_points[i].encoded.push(
          new GLatLng(
            tower.dead_points[i].raw[j].latitude,
            tower.dead_points[i].raw[j].longitude
          )
        );
      }
      //-----------------------------------------------------------------------
      // The first point also has to be the last or the polygon will not close.
      //-----------------------------------------------------------------------
      tower.dead_points[i].encoded.push(
        tower.dead_points[i].encoded[0]
      );
      tower.dead_points_polygons.push(new GPolygon(
        tower.dead_points[i].encoded, 
        tower.dead_fill_color, 
        1, 
        .5, 
        tower.dead_fill_color, 
        .5
      ));
    }
    tower.dead_points_loaded = true;
  }

  tower.init = true;
};

CCC.rf.draw_filled_circle = function(tower) {
  if (!tower.filled_circle_pts) {
    tower.filled_circle_pts = 
      CCC.rf.get_radius_points(tower,tower.radius_point);
  }

  if (!tower.init) {
    CCC.rf.init_tower_info(tower);
  }
  
  if (!tower.filled_circle_line) {
    tower.filled_circle_line = new GPolygon(
      tower.filled_circle_pts,
      tower.radius_border_color, 2, .5, tower.radius_fill_color, 0.5
    );
  }

  CCC.rf.map.addOverlay(tower.filled_circle_line);

  if (tower.points_loaded) {
    CCC.rf.map.addOverlay(tower.filled_polygon);
  }

  if (tower.dead_points_loaded) {
    for (var i in tower.dead_points_polygons) {
      CCC.rf.map.addOverlay(tower.dead_points_polygons[i]);
    }
  }
};

CCC.rf.remove_filled_circle = function(tower) {
  CCC.rf.map.removeOverlay(tower.filled_circle_line);
  if (tower.points_loaded) {
    CCC.rf.map.removeOverlay(tower.filled_polygon);
  }

  if (tower.dead_points_loaded) {
    for (var i in tower.dead_points_polygons) {
      CCC.rf.map.removeOverlay(tower.dead_points_polygons[i]);
    }
  }
};

CCC.rf.get_tower_data = function() {
  YAHOO.util.Connect.asyncRequest(
    "GET",
    CCC.rf.tower_data_loc+'?ts='+new Date().getTime(),
    {
      success  : CCC.rf.process_tower_data,
      failure  : CCC.rf.process_tower_data,
      timeout  : 30000,
      argument : { }
    }
  );
};

CCC.rf.process_tower_data = function(obj) {
  //var resp = obj.responseXML ? obj.responseXML : obj.responseText;
  var resp = obj.responseText;

  var error = "";
  if (obj.status != 200) {
    if (obj.status == -1) {
      error = "Server not responding, ";
    }
    error += obj.statusText + " ("+obj.status+")";
  }

  if (error.length > 0) {
    var dialog = CCC.util.html.create_simple_dialog_panel({
      body   : error,
      icon   : YAHOO.widget.SimpleDialog.ICON_WARN
    });

    return false;
  }

  CCC.rf.tower_data = eval("("+ resp + ")");

  var tul = CCC.util.dom.get_element('towers-ul');

  CCC.rf.tower_data.towers.sort(function(a,b) {
    if (a.name < b.name) {
      return(-1);
    } else if (a.name > b.name) {
      return(1);
    } else return(0);
  });

/**/
  for (var i in CCC.rf.tower_data.towers) { 
    CCC.rf.tower_data.towers[i].init = false;
    CCC.rf.tower_data.towers[i].points_loaded = false;
    CCC.rf.tower_data.towers[i].dead_points_loaded = false;

    CCC.rf.tower_data.towers[i].point = new GLatLng(
      CCC.rf.tower_data.towers[i].latitude,
      CCC.rf.tower_data.towers[i].longitude
    );
    CCC.rf.tower_data.towers[i].radius_point = CCC.rf.destination_point(
      CCC.rf.tower_data.towers[i].point, CCC.rf.tower_data.towers[i].radius
    );
    CCC.rf.tower_data.towers[i].max_radius_point = CCC.rf.destination_point(
      CCC.rf.tower_data.towers[i].point, CCC.rf.max_radius
    );
    CCC.rf.tower_data.towers[i].radius_marker = new GMarker(
      CCC.rf.tower_data.towers[i].radius_point
    );

    //CCC.rf.tower_data.towers[i].radius_fill_color   = "#AEACEF";
    CCC.rf.tower_data.towers[i].radius_fill_color   = "#ACEFB5";
    CCC.rf.tower_data.towers[i].radius_border_color = "#0000FF";
    CCC.rf.tower_data.towers[i].polygon_fill_color  = "#ACEFB5";
    CCC.rf.tower_data.towers[i].dead_fill_color     = "#FF0000";

    var icon = CCC.rf.icons["red_marker"];
    var elem = document.createElement('li');
    var status = "proposed tower site<br />Tentative in-service date: "+
      CCC.rf.tower_data.towers[i].details.inservice;
    elem.id = CCC.rf.tower_data.towers[i].point;
    elem.innerHTML = CCC.rf.tower_data.towers[i].name;
    tul.appendChild(elem);
    if (CCC.rf.tower_data.towers[i].details.status == 1) {
      icon = CCC.rf.icons["yellow_marker"];
      elem.style.listStyleImage = "url(images/sm-yellow-marker.png)";
      status = "under construction<br />Tentative in-service date: "+
        CCC.rf.tower_data.towers[i].details.inservice;
    } else if (CCC.rf.tower_data.towers[i].details.status == 2) {
      icon = CCC.rf.icons["green_marker"];
      elem.style.listStyleImage = "url(images/sm-green-marker.png)";
      status = 'in-service';
    }

    CCC.rf.tower_data.towers[i].tower_marker = CCC.rf.create_marker(
      CCC.rf.tower_data.towers[i].point,
      "Tower:<br />"+CCC.rf.tower_data.towers[i].name+"<br />"+
      "Status: "+status,
      {
        center     : false, 
        open_info  : false, 
        importance : 2, 
        icon       : icon
      }
    );

    GEvent.addListener(
      CCC.rf.tower_data.towers[i].tower_marker,
      "infowindowopen", 
      function () {
        var tower = CCC.rf.get_tower_from_point(this.getPoint());
        CCC.rf.remove_circle(tower);
        CCC.rf.remove_max_circle(tower);
        CCC.rf.draw_max_filled_circle(tower);
        //CCC.rf.remove_filled_circle(tower);
        CCC.rf.draw_filled_circle(tower);
        CCC.rf.center_map(tower.point);
      }
    );

    GEvent.addListener(
      CCC.rf.tower_data.towers[i].tower_marker, 
      "infowindowclose", 
      function () {
        var tower = CCC.rf.get_tower_from_point(this.getPoint());
        CCC.rf.remove_filled_circle(tower);
        CCC.rf.remove_circle(tower);
        CCC.rf.remove_max_filled_circle(tower);
        CCC.rf.draw_max_circle(tower);
        CCC.rf.draw_circle(
          tower,
          tower.point,
          tower.radius_point
        );
      }
    );

    YAHOO.util.Event.addListener(
      elem,
      'click',
      function () {
        GEvent.trigger(this,"click");
      },
      null,
      CCC.rf.tower_data.towers[i].tower_marker
    );

    CCC.rf.draw_max_circle(CCC.rf.tower_data.towers[i]);
    CCC.rf.draw_circle(
      CCC.rf.tower_data.towers[i],
      CCC.rf.tower_data.towers[i].point,
      CCC.rf.tower_data.towers[i].radius_point
    );

    if (CCC.rf.tower_data.center == CCC.rf.tower_data.towers[i].name) {
      CCC.rf.center_map(CCC.rf.tower_data.towers[i].point);
    }
  }
/**/
/*
    var point = new GLatLng(37.54933, -87.25892);
    var marker = CCC.rf.create_marker(point,"Tower: "+point, {
      center : true, open_info : true
    });
    var point = new GLatLng(37.4247, -87.2589);
    var marker = CCC.rf.create_marker(point,point, {
      center : false, open_info : false
    });
/**/
};

CCC.rf.get_tower_from_point = function(p) {
  for (var i in CCC.rf.tower_data.towers) { 
    if (CCC.rf.tower_data.towers[i].point == p) {
      return CCC.rf.tower_data.towers[i];
    }
  }

  return(null);
};

CCC.rf.set_display = function () {
    CCC.util.dom.get_element("lookup").style.visibility = "visible";

    var s = CCC.util.dom.get_element('street');
    if (s.value.length <= 0) {
      s.focus();
    } else {
      s.select();
    }
};

//-----------------------------------------------------------------------------
// Global initialization -- anything that goes here will take affect for all
// pages.
//-----------------------------------------------------------------------------
CCC.rf.begin = function() {
  //CCC.util.log.enable(true);
  //CCC.util.log.writer('entering begin');
  CCC.rf.lookup_tab = new YAHOO.widget.TabView(
    'lookup', { orientation: 'left' }
  );

  CCC.rf.lookup_tab.on('contentReady', function() {
    this.getTab(0).addListener('click', function () {
      var s = CCC.util.dom.get_element('street');
      if (s.value.length <= 0) {
        s.focus();
      } else {
        s.select();
      }
      GEvent.clearListeners(CCC.rf.map, 'click');
    });
    this.getTab(1).addListener('click', function () {
      var s = CCC.util.dom.get_element('fc_name');
      if (s.value.length <= 0) {
        s.focus();
      } else {
        s.select();
      }
      GEvent.clearListeners(CCC.rf.map, 'click');
    });
    this.getTab(2).addListener('click', function () {
      var s = CCC.util.dom.get_element('slct_name');
      if (s.value.length <= 0) {
        s.focus();
      } else {
        s.select();
      }
      GEvent.addListener(CCC.rf.map, 'click', CCC.rf.find_by_click);
    });
  });

  CCC.rf.init();
  CCC.rf.get_tower_data();

  //CCC.util.dom.get_element('address').disabled = false;

  setTimeout(CCC.rf.set_display,1000);
};

//-----------------------------------------------------------------------------
// Global de-initialization -- anything that goes here will take affect for all
// pages.
//-----------------------------------------------------------------------------
CCC.rf.end = function() {
  if (GUnload) {
    GUnload();
  }
};

//-----------------------------------------------------------------------------
// onload events need to go at the bottom
//-----------------------------------------------------------------------------
CCC.util.event.add_load_event(CCC.rf.begin);
CCC.util.event.add_unload_event(CCC.rf.end);
