var map = null;
var regularShapeLayer = new VEShapeLayer();
var premiumShapeLayer = new VEShapeLayer();
var descriptionTemplate;
var pinIds = {};
var mapData;
var currentSelectedPin;
var isPanning = false;
var initialMapPosition = {coordinates: new VELatLong(36.085731110623875, -86.72195434570311), zoom: 10};
var regularPinMinZoom = 12;
var useArtisticCoordinates = true;
var devToolDragShape = null;

$(document).ready(function() {
  var legend = new drilldownmenu({
    menuid: 'legend',
    menuheight: '650',
    breadcrumbid: 'drillcrumb',
    speed: 200
  });
  
  //get template
  $.ajax({
    type: 'GET',
    url: templateURL + '/description.html',
    dataType: 'html',
    success: function(data) {
      descriptionTemplate = data;
      //get data
      $.ajax({
        type: 'GET',
        url: baseURL + '/wp-content/members.json',
        dataType: 'json',
        success: function(data) {
          mapData = data;
          initSearchField();
          populateSponsors();
          initMap();
        },
        error: function(data) {
          alert('error loading data');
        }
      });
    }
  });
});

function initSearchField()
{
  var autocompleteData = _.pluck(mapData.companies, 'company');
  $('#search').autocomplete(autocompleteData, {
    matchContains: true,
    autoFill: true
  }).result(function(e, data){
    var company = _.detect(mapData.companies, function(company){ return company.company == data; });
    if (company)
    {
      location.hash = company.recnum;
    }
  });
}

function populateSponsors()
{
  var sponsorHTML = '<a href="#{recnum}"><img src="' + logoURL + '/sponsor_logos/{logo_tvurl}" alt="{company}" /></a>';
  var count = 0;
  _.each(mapData.companies, function(company){
    if (company.slevel == 1 && company.logo_tvurl != undefined)
    {
      $('#sponsors .items').append($.nano(sponsorHTML, company));
      count++;
    }
  });
  
  $('#sponsors .items img').batchImageLoad({
    loadingCompleteCallback: function(){
      $('#sponsors').scrollable({
        size: count,
        speed: 900
      }).circular().autoscroll(4000);
    }
  });
}

function initMap()
{
  map = new VEMap('map');
  map.SetCredentials('AqDy120vK2MbiPEa8HAbU3mcAX6Avq9LfuWcqQ5pNRWYZMyhu8h-CTpajVJFApMF');
  map.onLoadMap = onLoadMap;
  map.ShowMessageBox = true;
  map.LoadMap(initialMapPosition.coordinates, initialMapPosition.zoom);
  
  //disable mouseover/mouseout for infobox display
  map.AttachEvent('onmouseover', function(e) { if(e.elementID) return true; });
  map.AttachEvent('onmouseout', function(e) { if(e.elementID) return true; });
  
  map.AttachEvent('onclick', onMapClick);
  map.AttachEvent('onendzoom', onEndZoom);
  
  $(window).click(function(e){
    if ($('.ero').css('visibility') == 'visible')
    {
      map.HideInfoBox();
    }
  });
  
  $('.ero').live('click', function(e){
    e.stopPropagation();
  });
  
  $('#legend>ul>li>a').click(function(){
    location.hash = 'category-' + $(this).attr('href').substring(1);
  })
  
  $('#legend li.backcontrol').click(function(){
    location.hash = 'category-all';
  });
  
  bindHashChange();
  if (isUserLoggedIn)
  {
    initDevTool();
  }
}

function initDevTool()
{
  $.getScript(templateURL + '/js/json2.js', function(){
    $('#map').before('<div style="font-size: 1.3em"><a href="#" id="devmode">Enable Dev Mode</a></div>');
    $('#devmode').toggle(
      function(){
        $(this).text('Disable Dev Mode');
        map.DetachEvent('onclick', onMapClick);

        map.AttachEvent('onmousedown', devToolMouseHandler);
        map.AttachEvent('onmouseup', devToolMouseHandler);
        map.AttachEvent('onmousemove', devToolMouseHandler);

        $('#devmode').after('<div id="devtools" style="margin-top: 1em"><input type="button" id="devmode-savepositions" value="Save Artistic Positions" /><div id="devtools-result"></div></div>');
        $('#devmode-savepositions').click(function(){
          this.disabled = true;
          var newCoordinates = [];
          var shapeLayerCount = map.GetShapeLayerCount();
          for (var i = 0; i < shapeLayerCount; i++)
          {
            var shapeLayer = map.GetShapeLayerByIndex(i);
            var pinCount = shapeLayer.GetShapeCount();
            for (var j = 0; j < pinCount; j++)
            {
              var newval = {recnum: shapeLayer.GetShapeByIndex(j).recnum, coordinates: shapeLayer.GetShapeByIndex(j).GetPoints()[0]};
              newCoordinates.push(newval);
            }
          }
          $.post(baseURL + '/wp-content/plugins/ntcdataimport/artisticpositions-post.php', {positions: JSON.stringify(newCoordinates)}, function(data) {
            $('#devmode-savepositions')[0].disabled = false;
            $('#devtools-result').html(data);
          });
          
          return false;
        });

        return false;
      },
      function(){
        $(this).text('Enable Dev Mode');

        $('#devtools').remove();

        map.DetachEvent('onmousedown', devToolMouseHandler);
        map.DetachEvent('onmouseup', devToolMouseHandler);
        map.DetachEvent('onmousemove', devToolMouseHandler);

        map.AttachEvent('onclick', onMapClick);

        return false;
      }
    );
  });
}
function devToolMouseHandler(e)
{ 
   if (e.eventName == "onmousedown" && e.elementID != null)
   { 
      devToolDragShape = map.GetShapeByID(e.elementID); 
      return true; 
   }else if (e.eventName == "onmouseup") 
   { 
      devToolDragShape = null; 
   }else if (e.eventName == "onmousemove" && devToolDragShape != null) 
   { 
      var x = e.mapX; 
      var y = e.mapY; 
      pixel = new VEPixel(x, y); 
      var LL = map.PixelToLatLong(pixel); 
      devToolDragShape.SetPoints(LL); 
      return true; // prevent the default action 
   } 
}

function bindHashChange()
{
  $(window).bind('hashchange', function(e) {
    if (getCategoryFromHash())
    {
      populateMap();
    }
    else
    {
      if (pinIds[$.param.fragment()] == undefined)
      {
        $('#category-select:selected', 'select').removeAttr('selected');
        $('#category-select option:first').attr('selected', 'selected');
        populateMap();
      }
      else
      {
        if (useArtisticCoordinates)
        {
          useArtisticCoordinates = false;
          populateMap();
        }
        gotoPin(pinIds[$.param.fragment()]);
      }
    }
    return false;
  });
}

function unBindHashChange()
{
  $(window).unbind('hashchange');
}

function activateCategory()
{
  map.SetCenterAndZoom(initialMapPosition.coordinates, initialMapPosition.zoom);
  populateMap();
}

function onEndZoom()
{
  if (map.GetZoomLevel() > initialMapPosition.zoom)
  {
    if (useArtisticCoordinates == true)
    {
      useArtisticCoordinates = false;
      populateMap(true);
    }
    else
    {
      useArtisticCoordinates = false;
    }
  }
  else
  {
    if (useArtisticCoordinates == false)
    {
      useArtisticCoordinates = true;
      populateMap(true);
    }
    else
    {
      useArtisticCoordinates = true;
    }
  }
}

function onLoadMap()
{
  if ($.param.fragment() && _.isNumber(parseInt($.param.fragment())))
  {
    useArtisticCoordinates = false;
  }
  
  populateMap();
}

function getCategoryFromHash()
{
  var fragment = $.param.fragment();
  if (fragment.indexOf('category-') === 0)
  {
    return fragment.substring(9);
  }
  
  return undefined;
}

// this operates more as state machine, instead of properly decoupled code, because of the hash state and artistic coordinates state
function populateMap(ignoreHash)
{
  clearMap();
  var currentPin = null;
  var fragment = $.param.fragment();
  var category = getCategoryFromHash();
  _.each(mapData.companies, function(company){
    if ((category != undefined && category.toLowerCase() != 'all') && company.cat1 != category) {
      return;
    }
    if (useArtisticCoordinates)
    {
      var coordinates = new VELatLong(parseFloat(company.artistic_coordinates.lat), parseFloat(company.artistic_coordinates.long));
    }
    else
    {
      var coordinates = new VELatLong(parseFloat(company.coordinates.lat), parseFloat(company.coordinates.long));
    }
    var pin = new VEShape(VEShapeType.Pushpin, coordinates);
    
    pin.recnum = company.recnum;
    
    if (parseInt(company.slevel) <= 2 && company.logo_tvurl != undefined)
    {
      pin.SetCustomIcon(logoURL + '/' + company.logo_tvurl);
      if (parseInt(company.slevel) == 1)
      {
        pin.SetZIndex(1005);
      }
      else
      {
        pin.SetZIndex(1001);
      }
      premiumShapeLayer.AddShape(pin);
    }
    else
    {
      pin.SetCustomIcon(templateURL + '/i/star.png');
      if (category != undefined && category.toLowerCase() != 'all') {  // if we are filtering by category, add all shapes to the same layer
        premiumShapeLayer.AddShape(pin);
      }
      else
      {
        //pin.SetMinZoomLevel(regularPinMinZoom);
        regularShapeLayer.AddShape(pin);
      }
    }
    if (!ignoreHash && fragment == company.recnum)
    {
      currentPin = pin;
    }
    pinIds[company.recnum] = pin.GetID();
  });
  
  map.AddShapeLayer(regularShapeLayer);
  map.AddShapeLayer(premiumShapeLayer);
  
  if (currentPin)
  {
    useArtisticCoordinates = false;
    gotoPin(currentPin.GetID());
  }
  else if (!ignoreHash && category != undefined && category.toLowerCase() != 'all')
  {
    map.SetMapView(premiumShapeLayer.GetBoundingRectangle());
  }
}

function clearMap()
{
  pinIds = {};
  
  map.DeleteShapeLayer(regularShapeLayer);
  map.DeleteShapeLayer(premiumShapeLayer);
  regularShapeLayer.DeleteAllShapes();
  premiumShapeLayer.DeleteAllShapes();
  map.Clear();
  regularShapeLayer = new VEShapeLayer();
  premiumShapeLayer = new VEShapeLayer();
}

function onMapClick(e)
{
  if (e.elementID != null)
  {
    var pin = map.GetShapeByID(e.elementID);
    unBindHashChange();
    location.hash = pin.recnum;
    loadCompanyDescription(pin, true);
    bindHashChange();
  }
}

function loadCompanyDescription(pin, forceShow, sync)
{
  map.HideInfoBox();
  if (!mapData.companies[pin.recnum].description)
  {
    mapData.companies[pin.recnum].description = 'No description available.';
  }
  
  if (mapData.companies[pin.recnum].logo_tvurl)
  {
    mapData.companies[pin.recnum].logoHTML = $.nano('<h2><img src="' + logoURL + '/large_logos/{logo_tvurl}" alt="{company}" /></h2>', mapData.companies[pin.recnum]);
  }
  else
  {
    mapData.companies[pin.recnum].logoHTML = '<h2>' + mapData.companies[pin.recnum].company + '</h2>';
  }
  
  pin.SetDescription($.nano(descriptionTemplate, mapData.companies[pin.recnum]));
  
  if (forceShow == true)
  {
    if (!$('#' + pin.Primitives[0]._iconElement.id).find('img')[0].complete)
    {
      $('#' + pin.Primitives[0]._iconElement.id).find('img').load(function(){
        $(this).unbind('load');
        VEShowVEShapeERO(pin.Primitives[0]._iconElement.id, map.GUID);
      });
    }
    else
    {
      VEShowVEShapeERO(pin.Primitives[0]._iconElement.id, map.GUID);
    }
  }
  recordCompanyView(pin.recnum);
}

//overriding core bing maps function to prevent some event weirdness
function VECreateVEShapeERO(b, d) {
  if (b._IconContent == null) {
    var a = [],
        f = b.GetPrimitive(0),
        e = f.iid;
    if (f.type != VEShapeType.Pushpin) e = Msn.Drawing.GetLabelUID(e);
    var c = b._customIcon;
    if (c == null) c = b.IconUrl;
    if (c.indexOf("<") < 0) c = '<img src="' + c + '" />';
    a.push("<div onmouseout='if (VEMap._GetMapFromGUID(");
    a.push(d);
    a.push(").FireEvent(\"onmouseout\"))return;' onmouseover='if (VEMap._GetMapFromGUID(");
    a.push(d);
    a.push(').FireEvent("onmouseover"))return;VEShowVEShapeERO("');
    a.push(e);
    a.push('",');
    a.push(d);
    a.push(");' onmousedown='if (VEMap._GetMapFromGUID(");
    a.push(d);
    a.push(').FireEvent("onmousedown"))return;VEDragVEShapeDown("');
    a.push(e);
    a.push('",');
    a.push(d);
    a.push(");'> ");
    a.push(c);
    a.push("</div>");
    b._IconContent = a.join("")
  }
  return b._IconContent;
}

function gotoPin(pinID)
{
  currentSelectedPin = map.GetShapeByID(pinID);
  if (map.GetZoomLevel() < regularPinMinZoom)
  {
    map.AttachEvent('onendzoom', retryGotoPin);
    map.SetZoomLevel(17);
  }
  else
  {
    bindChangeView();
    map.SetCenter(new VELatLong(currentSelectedPin.Latitude, currentSelectedPin.Longitude));
  }
}

function retryGotoPin()
{
  map.DetachEvent('onendzoom', retryGotoPin);
  gotoPin(currentSelectedPin.GetID());
}

function bindChangeView()
{
  // need both (plus this crazy even binding below) because of inconsistencies in events that are fired from map
  map.AttachEvent('onstartpan', onStartPan);
  map.AttachEvent('onchangeview', onChangeViewLoadDescription);
}

function unbindChangeView()
{
  map.DetachEvent('onstartpan', onStartPan);
  map.DetachEvent('onendpan', onEndPan);
  map.DetachEvent('onchangeview', onChangeViewLoadDescription);
}

function onStartPan()
{
  isPanning = true;
  map.AttachEvent('onendpan', onEndPan);
}

function onEndPan()
{
  isPanning = false;
  onChangeViewLoadDescription();
}

function onChangeViewLoadDescription()
{
  if (isPanning)  // prevent double display because of inconsistencies in events
  {
    return;
  }
  isPanning = false;
  unbindChangeView();
  setTimeout(function(){
    loadCompanyDescription(currentSelectedPin, true, true);
  }, 100);
}

function recordAction(category, action, label)
{
  try
  {
    pageTracker._trackEvent(category, action, label);
  }catch(err){}
}

function recordCompanyView(recnum)
{
  recordAction('Company Events', 'view', recnum);
}

function recordCompanyClickThru(link, recnum)
{
  recordAction('Company Events', 'clickthru', recnum);
  setTimeout('document.location = "' + link.href + '"', 100);
}
