var OUR_DEFAULT_ZOOM_LEVEL = 9;
var MAP_IMAGES_URL = guideConfig['imagePath'] + 'profile_map/';
var ENTITY_TRACKING_PATH = '/tracker/entity';
var DIRECTIONS_TRACKING_PAGETYPE = 'maps_directions';
var PRINTABLE_DIRECTION_PATH = '/profile/map/print';
var INFOWIN_TRACKING_PAGETYPE = 'maps_nearby_customer_windoid';
var PFP_ID_PREFIX = 'pfp';
var CONTAINER_IDS = {
  'map': 'map-container',
  'form': 'form-container',
  'mode': 'mode-container',
  'error': 'error-container',
  'directions': 'directions-container',
  'printForm': 'print-container'
};

var IMAGE_NAMES = {
  'ratings-suffix': '-rating.png',
  'infowin-bg': 'maps-info-window-bg.png',
  'loading': 'loading.gif'
};

var ICON_CONFIGS = {
  'entity': { 'name': 'entity.png', 'height': 30 },
  'from': { 'name': 'start-ptr.png', 'topOffset': 24, 'leftOffset': 10 },
  'to': { 'name': 'end-ptr.png', 'topOffset': 24, 'leftOffset': 10 },
  'pfp': { 'name': 'pfp-marker.png', 'height': 17 }
};

var map;
var printedMap;
var displayedInfoWin;
var entityPoint, entityMarker;
var loadingImage;
var fromPoint, toPoint;
var formHeadingSelect;
var formAddrInput;
var address;
var marker;
var infoWinOpener;
var directionsMode=false;
var sessId;
var routeRes;
var myBB;

pedro.event.addToOnLoad(function(){
  startMap(window['entity'].location);
  makeForm();
  makePrintForm();
  entityPoint = makePoint(window['entity']);
  entityMarker = makeMarker(entityPoint,window['entity']);
  pfpspoint = primePfps();
  map.replaceShapes(entityMarker);
  map.addShapes(pfpspoint);
});

var MapPrintController = {};

MapPrintController.print = function(entityId) {
  var pContainerId = CONTAINER_IDS['printForm'];
  var pContainer = byId(pContainerId);

  //Enable Frame if driving directions exist
  if (directionsMode == true) {
    byId(pContainerId + '-form-isDriving').value = 'true';
  }else {
    byId(pContainerId + '-form-isDriving').value = 'false';
  }

  global.createWindow('', PRINT_PROFILE_MAP_SPEC);
  byId(pContainerId + '-form').submit();
}

//Initialize Map
function startMap(loc){
  var zoomControl = new MQA.LargeZoomControl()
  var viewControl = new MQA.ViewControl();
  var trafficControl = new MQA.TrafficControl();

  map=new MQA.TileMap(byId(CONTAINER_IDS['map']),OUR_DEFAULT_ZOOM_LEVEL,new MQA.LatLng(loc['lat'],loc['lon']),"map");
  map.addControl(zoomControl,new MQA.MapCornerPlacement(MQA.MapCorner.TOP_LEFT, new MQA.Size(2, 50)));
  map.addControl(viewControl, new MQA.MapCornerPlacement(MQA.MapCorner.TOP_RIGHT, new MQA.Size(77, 0)))
  map.addControl(trafficControl,new MQA.MapCornerPlacement(MQA.MapCorner.TOP_RIGHT, new MQA.Size(0,0)));
  map.setLogoPlacement(MQA.MapLogo.SCALES, new MQA.MapCornerPlacement(MQA.MapCorner.TOP_RIGHT, new MQA.Size(0, 23)));
  //Shrink default map (units=pixels)
  map.setSize(new MQA.Size(458,402));
}

//Making Form for origin and destination direction.
function makeForm(){
  var formId = CONTAINER_IDS['form'];
  //Textbox for directions
  formAddrInput = input({'type': 'input', 'id': formId + '-address-input'});
  //Pull-downlist
  formHeadingSelect = select({'id': formId + '-heading-select'},
      option({ 'value': 'from' }, 'From'),
      option({ 'value': 'to' }, 'To'));
  //Creates actual form and adds features
  var formElem = form({'method': 'GET', 'action': '#'},
      formHeadingSelect,
      formAddrInput,
      input({'class': 'directions-submit-button', 'type': 'submit', 'id': formId + '-submit', 'value': 'Get Directions'}));

  pedro.event.addEventListener(formElem, 'submit', submitDirectionsForm, false, true);
  if (byId(formId)) {
  	  byId(formId).appendChild(formElem);
  }
}

function submitDirectionsForm() {
  directionsMode = true;
  fetchDirections(formHeadingSelect.options[formHeadingSelect.selectedIndex].value,
                  formAddrInput.value,window['entity']);
}

function fetchDirections(heading, address,info) {
  clearDirections();
  hidePOI();
  makePrintForm();

  // Clear all non pfp-style markers from map.
  if (displayedInfoWin) {
    displayedInfoWin.close();
    displayedInfoWin = null;
  }

  if (address.length == 0) {
    displayError('No address specified.');
    return;
  }

  /*Mapquest geocoding*/
  var geoExec = new MQExec(geocodeServer, serverPath, serverPort, proxyServer, proxyPath, proxyPort);

  var routeExec = new MQExec(routeServer, serverPath, serverPort, proxyServer, proxyPath, proxyPort );

  var loc = info['location'];

  var gaToCollection = new MQLocationCollection("MQGeoAddress");
  var addr = new MQAddress();

  addr.setCity(loc['city']);
  addr.setPostalCode(loc['zip']);
  addr.setStreet(loc['street']);
  addr.setState(loc['state']);

  geoExec.geocode(addr,gaToCollection,null);

  geoAddr2=gaToCollection.get(0);

  var gaCollection = new MQLocationCollection("MQGeoAddress");

  var addr = new MQSingleLineAddress();

  addr.setAddress(formAddrInput.value);

  geoExec.geocode(addr,gaCollection,null);

  var geoAddr1 = gaCollection.get(0);

  if (heading == 'from'){
    toPoint = geoAddr1;
    fromPoint = geoAddr2;
  }else{
    fromPoint = geoAddr1;
    toPoint = geoAddr2;
  }

  var session = new MQSession();
  routeRes = new MQRouteResults();
  var wayPoints = new MQLocationCollection();
  myBB = new MQA.RectLL(new MQLatLng(),new MQLatLng());

  wayPoints.add(toPoint);
  wayPoints.add(fromPoint);

  var routeOpt = new MQRouteOptions();
  routeOpt. setMaxShapePointsPerManeuver(200);

  sessId = routeExec.createSessionEx(session);
  routeExec.doRoute(wayPoints,routeOpt,routeRes,sessId,myBB);

  map.addRouteHighlight(myBB,"http://map.access.mapquest.com",sessId,true);

  //Create End Icon
  var endIcon = new MQA.Icon("/web/guide/images/profile_map/end.gif", 0, 0, true, false);

  //Create Origin Icon
  var startIcon = new MQA.Icon("/web/guide/images/profile_map/start.gif", 0, 0, true, false);

  //Create Origin Poi and add to the Map
  var startPoi = new MQA.Poi(toPoint.getMQLatLng(), startIcon);
  var route1 = new MQA.ShapeCollection();
  route1.add(startPoi);
  map.addShapes(route1);

  //Create Destination Poi and add to the Map
  var endPoi = new MQA.Poi(fromPoint.getMQLatLng(), endIcon);
  var route2 = new MQA.ShapeCollection();
  route2.add(endPoi);
  map.addShapes(route2);

  // geoExec.geocode(address, gotGeoCode, null, 'a', nowGetDirections);

  // Log the request to fetch directions
  global.trackEntity(ENTITY_TRACKING_PATH
    + '?entityId=' + window['entity']['id']
    + '&pageType=' + DIRECTIONS_TRACKING_PAGETYPE);

  displayDirectionsData(routeRes, fromPoint, toPoint);
}

//Called from printableMap.jsp
function printMap(){
  if(myBB){
  map.addRouteHighlight(myBB,"http://map.access.mapquest.com",sessId,true);

  var endIcon = new MQA.Icon("/web/guide/images/profile_map/end.gif", 0, 0, true, false);

  //Create Origin Icon
  var startIcon = new MQA.Icon("/web/guide/images/profile_map/start.gif", 0, 0, true, false);

  //Create Origin Poi and add to the Map
  var startPrintPoi = new MQA.Poi(toPoint.getMQLatLng(), startIcon);
  var printRoute1 = new MQA.ShapeCollection();
  printRoute1.add(startPrintPoi);
  map.addShapes(printRoute1);

  //Create Destination Poi and add to the Map
  var endPrintPoi = new MQA.Poi(fromPoint.getMQLatLng(), endIcon);
  var printRoute2 = new MQA.ShapeCollection();
  printRoute2.add(endPrintPoi);
  map.addShapes(printRoute2);
  map.showStaticMap();
  }
  else{
  	map.showStaticMap();
  }
}

function makePoint(info) {
  var loc = info['location'];
  return new MQA.LatLng(loc['lat'],loc['lon']);
}


function makeMarker(point,info,options) {

  marker = new MQA.Poi(point);

  options = options || {};
  var innerDiv = div({ 'class': 'infowin-inner' },
    a({ 'class': 'infowin-header', 'name': 'infowin-header',
      'href': info.profileURL }, info.name));
  var innerContent = div({'class':'infowin-inner'},p({'class':'infowin-category'},info.category));
  innerContent.appendChild(p({'class':'infowin-rating'},getRatingImage(info.rating)));
  innerContent.appendChild(p({'class':'infowin-address'},info.location.street, br(),info.location.city + ',' + info.location.state + ',' + info.location.zip));
  innerContent.appendChild(p({ 'class': 'infowin-phone' }, info.phone));
    var linkbar = p({ 'class': 'infowin-link-bar' },
    a({ 'name': 'map-infowin-reviews', 'href': info.reviewsURL }, 'Reviews'));
    if (info.websiteURL) { // XXX FIX WEBSITEURL IN CONTROLLER.
    linkbar.appendChild(span(' | '));
    linkbar.appendChild(a({ 'name': 'map-infowin-website',
        'href': info.websiteURL }, 'Website'));
    }
    innerContent.appendChild(linkbar);
    if (info.description) {
      innerContent.appendChild(p({ 'class': 'infowin-description' }, info.description));
  }
  /////
  if (options['directions']) {
    if (!options['heading'] || options['heading'] != 'from') {
      fromLink = a({'href': '#'}, 'From');
      pedro.event.addEventListener(fromLink, 'click', function() { options['heading'] = 'from'; makeMarker(info, point, options); }, false, true);
    }
    if (!options['heading'] || options['heading'] != 'to') {
      toLink = a({'href': '#'}, 'To');
      pedro.event.addEventListener(toLink, 'click', function() { options['heading'] = 'to'; makeMarker(info, point, options); }, false, true);
    }

    innerContent.appendChild(
      p({'class': 'infowin-directions'},
        span({'class': 'infowin-directions-span'}, 'Directions: '),
        fromLink || span({'class': 'infowin-disabled-link'}, 'From'),
        span(' | '),
        toLink || span({'class': 'infowin-disabled-link'}, 'To')));

    if (options['heading']) { // Build out directions form if necessary.
      dirForm = form({'class': 'infowin-form', 'method': 'GET', 'action': '#'},
        (dirInput = input({'class': 'infowin-directions-input'})),
        input({'class': 'directions-submit-button infowin-directions-submit', 'type': 'submit', 'value': 'Get Directions'}));
      innerContent.appendChild(dirForm);
      pedro.event.addEventListener(dirForm, 'submit', function() { formAddrInput.value = dirInput.value; fetchDirections(options['heading'], dirInput.value); }, false, true);
      dirInput.value = (options['heading'] == 'from') ? 'Starting address...' : 'Destination address...';
    }
  }
  ////
  marker.setValue('infoTitleHTML',innerDiv.innerHTML);
  marker.setValue('infoContentHTML', innerContent.innerHTML);
  marker.setValue('minInfoWindowWidth',250);
  marker.setValue('maxInfoWindowWidth',300);

  //openInfoWin(info,point);
  myPOIS = new MQA.ShapeCollection();
  myPOIS.add(marker);
  return myPOIS;
}

function makeIcon(conf) {
  return new MQA.Icon(MAP_IMAGER_URL + conf['name'], conf['topOffset'], conf['leftOffset']);
}


function displayDirectionsData(routeRes, fromPoint, toPoint){
  var contId = CONTAINER_IDS['directions'];
  var cont = byId(contId);

  cont.appendChild(
    div({'id': contId + '-from-to'},
      p({'id': contId + '-from-addr'},
        img({'src': MAP_IMAGES_URL + 'start.gif', 'id': 'from-image'}),
        span({'id': 'directions-container-from'}, ' ', toPoint.getStreet(),' ',toPoint.getCity(),' ',toPoint.getState(),' ',toPoint.getCountry(),' ',toPoint.getPostalCode())),
      p({'id': contId + '-to-addr'},
        img({'src': MAP_IMAGES_URL + 'end.gif', 'id': 'to-image'}),
        span({'id': 'directions-container-to'}, ' ', fromPoint.getStreet(),' ',fromPoint.getCity(),' ',fromPoint.getState(),' ',fromPoint.getCountry(),' ',fromPoint.getPostalCode()))));

  var map_direction = document.getElementById('map-directions');
  pedro.element.util.removeAllChildren(map_direction);
  map_direction.appendChild(document.createTextNode('Directions '));

  cont.appendChild(
    ul({'id': contId + '-totals'},
      li({'id': contId + '-total-distance'},
        span({'class': contId + '-total-label'}, 'Total Distance:'),
        getDistanceFromDirectionsData(routeRes)),
      li({'id': contId + '-total-time'},
        span({'class': contId + '-total-label'}, 'Total Time:'),
        getTimeFromDirectionsData(routeRes))));

  var headers = new Array();
  headers.push("DRIVING STEPS");
  headers.push("Distance");
  headers.push("Time");

  var directionsTable = getRouteDirections(routeRes,true, true, true, true, headers);

  cont.appendChild(directionsTable);

  addDirectionsToPrintForm(routeRes, fromPoint, toPoint);
}

function addDirectionsToPrintForm(routeRes, fromPoint, toPoint) {

  var pContainerId = CONTAINER_IDS['printForm'];
  var formFields = byId(pContainerId + '-form-fieldset');

  var toAddressString = toPoint.getStreet()+ " " + toPoint.getCity() + " "
                + toPoint.getState() + " " + toPoint.getCountry() +" "+ toPoint.getPostalCode();
  var fromAddressString = fromPoint.getStreet()+ " " + fromPoint.getCity() + " "
                + fromPoint.getState() + " " + fromPoint.getCountry() +" "+ fromPoint.getPostalCode();

  formFields.appendChild(input({'name':'start','type':'hidden','value':toAddressString}));
  formFields.appendChild(input({'name':'end','type':'hidden','value':fromAddressString}));
  formFields.appendChild(input({'name':'duration','type':'hidden','value':getTimeFromDirectionsData(routeRes)}));
  formFields.appendChild(input({'name':'distance','type':'hidden','value':getDistanceFromDirectionsData(routeRes)}));

  var myManDist;
  for (var i = 0; i < routeRes.getTrekRoutes().get(0).getManeuvers().getSize(); i++) {
      myManDist = Math.round(routeRes.getTrekRoutes().get(0).getManeuvers().get(i).getDistance()*100)/100;
      trekString = routeRes.getTrekRoutes().get(0).getManeuvers().get(i).getNarrative()
        + " (DISTANCE:" + myManDist + " mi)";
      formFields.appendChild(input({'name':'steps','type':'hidden','value':trekString}));
  }
}

function getTimeFromDirectionsData(routeRes) {
  var est;
  if(routeRes.getTime() > 3600){
     est = formatTime(routeRes.getTime() , "%h hours %m minutes");
  }else{
     est = formatTime(routeRes.getTime() , "%m minutes");
  }
  return est;
}

function getDistanceFromDirectionsData(routeRes) {
   var dist;
   dist = formatDistance(routeRes.getDistance()) + " miles.";
   return dist;
}

function getRatingImage(rating) {
  if (isNaN(parseFloat(rating)))
    return null;
  rating = parseInt(Math.round(rating));
  return img({'src':MAP_IMAGES_URL + rating + IMAGE_NAMES['ratings-suffix']});
}

function hidePOI(){
   map.removeShape(marker);
   map.removeAllShapes(infoWinOpener);
}

function makePrintForm() {
    clearPrintForm();

    var pContainerId = CONTAINER_IDS['printForm'];
    var pContainer = byId(pContainerId);
    var entity = window['entity'];
    var formElem = form({'id': pContainerId + '-form',
            'method': 'POST',
            'action': PRINTABLE_DIRECTION_PATH,
            'target': PRINT_PROFILE_MAP_SPEC.name});
    var formFields = div({'id': pContainerId + '-form-fieldset'},
            input({'name':'entityId','type':'hidden','value':entity['id']}),
            input({'id':pContainerId + '-form-imageUrl', 'name':'mapImageUrl','type':'hidden'}),
            input({'id':pContainerId + '-form-isDriving', 'name':'isDriving','type':'hidden','value':'true'}));

    formElem.appendChild(formFields);
    pContainer.appendChild(formElem);
}

function primePfps() {
  if (window['pfpInfo']){
    var pfpsCollection = new MQA.ShapeCollection();

    for (var i = 0; i < 3 && i < window['pfpInfo'].length; i++) {
      var info = window['pfpInfo'][i];
      var point = makePoint(window['pfpInfo'][i]);
      var otherNearby = OtherNearbyModuleDummy(point,info);
      var pfps = new MQA.Icon("/web/guide/images/profile_map/pfp-marker.png", 0, 0, true, false);
      var innerDiv = div({ 'class': 'infowin-inner' },
      a({ 'class': 'infowin-header', 'name': 'infowin-header',
          'href': info.profileURL }, info.name));
      var innerContent = div({'class':'infowin-inner'},p({'class':'infowin-category'},info.category));
      innerContent.appendChild(p({'class':'infowin-rating'},getRatingImage(info.rating)));
      innerContent.appendChild(p({'class':'infowin-address'},info.location.street, br(),info.location.city + ',' + info.location.state + ',' + info.location.zip));
      innerContent.appendChild(p({ 'class': 'infowin-phone' }, info.phone));
      var linkbar = p({ 'class': 'infowin-link-bar' },
          a({ 'name': 'map-infowin-reviews', 'href': info.reviewsURL }, 'Reviews'));
      if (info.websiteURL) { // XXX FIX WEBSITEURL IN CONTROLLER.
        linkbar.appendChild(span(' | '));
        linkbar.appendChild(a({ 'name': 'map-infowin-website',
          'href': info.websiteURL }, 'Website'));
      }
      innerContent.appendChild(linkbar);
      if (info.description) {
        innerContent.appendChild(p({ 'class': 'infowin-description' }, info.description));
      }
      infoWinOpener = new MQA.Poi(point,pfps);
      infoWinOpener.setValue('infoTitleHTML',innerDiv.innerHTML);
      infoWinOpener.setValue('infoContentHTML', innerContent.innerHTML);
      pfpsCollection.add(infoWinOpener);
      infoWinOpener.setValue('maxInfoWindowWidth',300);
      pedro.event.addEventListener(byId(PFP_ID_PREFIX + '-title-' + i), 'click', otherNearby, false, true);
    }
    return pfpsCollection;
  }
}

function OtherNearbyModuleDummy(point,info) {
    	return function() { OtherNearbyModule(point, info); }
  	}


function OtherNearbyModule(point, info){
	var OtherCollection = new MQA.ShapeCollection();
	var pfpinfo = new MQA.Icon("/web/guide/images/profile_map/pfp-marker.png", 0, 0, true, false);
	
	var innerDiv = div({ 'class': 'infowin-inner' },
      a({ 'class': 'infowin-header', 'name': 'infowin-header',
        'href': info.profileURL }, info.name));
      var innerContent = div({'class':'infowin-inner'},p({'class':'infowin-category'},info.category));
      innerContent.appendChild(p({'class':'infowin-rating'},getRatingImage(info.rating)));
      innerContent.appendChild(p({'class':'infowin-address'},info.location.street, br(),info.location.city + ',' + info.location.state + ',' + info.location.zip));
      innerContent.appendChild(p({ 'class': 'infowin-phone' }, info.phone));
      var linkbar = p({ 'class': 'infowin-link-bar' },
      a({ 'name': 'map-infowin-reviews', 'href': info.reviewsURL }, 'Reviews'));
    if (info.websiteURL) { // XXX FIX WEBSITEURL IN CONTROLLER.
      linkbar.appendChild(span(' | '));
      linkbar.appendChild(a({ 'name': 'map-infowin-website',
        'href': info.websiteURL }, 'Website'));
    }
    innerContent.appendChild(linkbar);
    if (info.description) {
      innerContent.appendChild(p({ 'class': 'infowin-description' }, info.description));
  }
  
   otherInfo = new MQA.Poi(point,pfpinfo);
   otherInfo.setValue('infoTitleHTML',innerDiv.innerHTML);
   otherInfo.setValue('infoContentHTML',innerContent.innerHTML);
   OtherCollection.add(otherInfo);
   map.addShapes(OtherCollection);
   for(var i=0; i < OtherCollection.getSize(); i++){
  			  map.setCenter(OtherCollection.getAt(i).getLatLng(),map.getZoomLevel());
  			  OtherCollection.getAt(i).showInfoWindow();
 	  }
    global.trackEntity(ENTITY_TRACKING_PATH + '?entityId=' + info['id'] + '&pageType=' + INFOWIN_TRACKING_PAGETYPE);
}

function clearDirections() {
  pedro.element.util.removeAllChildren(byId(CONTAINER_IDS['directions']));
  pedro.element.util.removeAllChildren(byId(CONTAINER_IDS['error']));
}

function clearPrintForm() {
  pedro.element.util.removeAllChildren(byId(CONTAINER_IDS['printForm']));
}

function displayError(error) {
  byId(CONTAINER_IDS['error']).appendChild(p(error));
}

