var smsDeals = window.smsDeals || {};

(function() {
  
  var gMaps = window.google && window.google.maps ? google.maps : null;
  if (gMaps) {
    var maps;

    smsDeals.Maps = maps = function Maps(elementId, mapConfig, markerData, subscriberMarkerData) {
      if (!gMaps) return;
      var t = maps.currentMap = this;
      var config = t.config = mapConfig && maps.config[mapConfig] ? maps.config[mapConfig]() : null;
      var defaultConfig = maps.config.__defaultConfig(t);

      t.elementId = elementId;

      for (var x in config) {
        if (!t[x]) t[x] = config[x];
      }
    
      for (var x in defaultConfig) {
        if (!t[x]) t[x] = defaultConfig[x];
      }

      t.element = document.getElementById(t.elementId)
      if (t.locationsListId) {
        t.locationsList = document.getElementById(t.locationsListId);
      }
      if (t.removalsListId) {
        t.removalsList = document.getElementById(t.removalsListId);
      }
      t.locations = 0;
      t.options.center = t.getCenter();
      t.map = new gMaps.Map(t.element, t.options);
      t.markers = {};
      t.parseMarkers(markerData);
      t.subscriberMarkers = t.parseSubscriberMarkers(subscriberMarkerData);
      if (t.events) t.events();
      if (t.postInitialize) t.postInitialize.call(t);
    };
  
    maps.config = {
      __defaultConfig: function(t) {
        return {
          lat: 41.95,
          lng: -88.05,
          state: "",
          options: {
            zoom: 9,
            mapTypeId: gMaps.MapTypeId.ROADMAP,
            mapTypeControl: false,
            scrollwheel: false
          },
          events: function() {
            this.events = {
              click: gMaps.event.addListener(t.map, 'click', function(event) {
                t.setLocation.call(t, event.latLng);
              })
            };
          },
          elementId: 'sms-map-area',
          locationsListId: 'sms-locations',
          removalsListId: 'sms-removals',
          defaultRadius: 5,
          canAdd: true
        };
      },
      subscriberMap : function() {
        return {
          objectName: "subscriber[subscriber_locations_attributes][]",
          usesRadius: false,
          locationsListId: 'sms-locations',
          removalsListId: 'sms-removals'
        };
      },
      advertiserMap : function() {
        return {
          objectName: "deal[deal_locations_attributes][]",
          usesRadius: true,
          locationsListId: null,
          removalsListId: null
        };
      },
      miniMap: function () {
        return {
          options: {
            zoom: 9,
            mapTypeId: gMaps.MapTypeId.ROADMAP,
            disableDefaultUI: true,
            scaleControl: true,
            mapTypeControl: false,
            scrollwheel: false
          },
          events: function() {
            this.events = {};
          },
          usesRadius: true,
          locationsListId: null,
          removalsListId: null,
          postInitialize: function() {
            this.resizeToFit({markers: this.markers});
          }
        }
      },
      reportMap: function() {
        return {
          options: {
            zoom: 9,
            mapTypeId: gMaps.MapTypeId.ROADMAP,
            scaleControl: true,
            mapTypeControl: false,
            scrollwheel: false
          },
          events: function() {
            this.events = {};
          },
          usesRadius: true,
          locationsListId: null,
          removalsListId: null,
          canAdd: false,
          postInitialize: function() {
            this.resizeToFit({markers: this.markers, subscriberMarkers: this.subscriberMarkers});
          }
        };
      }
    };
  
    maps.prototype.resizeToFit = function(markerSets) {
      var markers;
      var locations = false;
      var bounds = new gMaps.LatLngBounds();
      for (var markerSet in markerSets) {
        if (markerSets.hasOwnProperty(markerSet)) {
          markers = markerSets[markerSet];
          for (var x in markers) {
            if (markers.hasOwnProperty(x)) {
              locations = true;
              bounds.extend(markers[x].location.location);
              if (markers[x].getRadiusMarkerPaths) {
                radiusPaths = markers[x].getRadiusMarkerPaths();
                if (radiusPaths) {
                  radiusPaths.forEach(function(b) {
                    b.forEach(function(a) {
                      bounds.extend(a); 
                    });
                  });
                }
              }
              var ne = bounds.getNorthEast(),
              sw = bounds.getSouthWest()
              diff = Math.abs(ne.lat()) - Math.abs(sw.lat());
              if (diff < .3) {
                bounds.extend(new gMaps.LatLng(ne.lat() - (.3-diff) / 2, ne.lng()));
                bounds.extend(new gMaps.LatLng(sw.lat() + (.3-diff) / 2, sw.lng()));
              }
            }
          }
        }
      }
      if (locations) this.map.fitBounds(bounds);
    }
  
    maps.prototype.parseMarkers = function(markerData) {
      if (markerData) {
        for (var location, x, i = 0, mdLength = markerData.length; i < mdLength; i++) {
          x = markerData[i];
          location = this.getLocation(new gMaps.LatLng(x.lat, x.lng), {formatted_address: x.name}, x.radius);
          this.currentMarker = new this.marker(this.map, location, true, x.id);
          this.addLocation(location);
        }
      }
    }
  
    maps.prototype.parseSubscriberMarkers = function(markerData) {
      var markers = {};
      if (markerData) {
        for (var location, x, i = 0, mdLength = markerData.length; i < mdLength; i++) {
          x = markerData[i];
          location = this.getLocation(new gMaps.LatLng(x.lat, x.lng));
          markers[i] = new this.subscriberMarker(this.map, location);
        }
      }
      return markers;
    }

    maps.prototype.getCenter = function() {
      return new gMaps.LatLng(this.lat, this.lng);
    };
  
    
    maps.prototype.getDefaultRadius = function() {
      return this.usesRadius ? this.defaultRadius : null
    }
  
    maps.prototype.geocoder = new gMaps.Geocoder();
  
    maps.prototype.getLocation = function(location, result, radius) {
      var loc = new this.location(location, result, radius);
      if (loc.validLocation && this.map.getZoom() < 8) {
        this.map.setZoom(8);
      }
      return loc;
    }
  
    maps.prototype.setLocation = function(location) {
      var t = this;
      t.geocoder.geocode({
        latLng: location
      }, function(results, status) {
        var city_state = [],
        types = ['locality', 'administrative_area_level_1'],
        type, f, c;
        for (type in types) {
          for (f in (results[0].address_components)) {
	          c = results[0].address_components[f];
            if (c.types && c.types.join('').indexOf(types[type]) >= 0) {
               city_state.push(c.short_name);
               break;
            }
          }
        }
        results[0].formatted_address = city_state.join(', ');
        t.placeMarker.call(t, (t.currentLocation = t.getLocation(location, results[0], t.getDefaultRadius())));
      });
    }
  
    maps.prototype.search = function() {
      var input = document.getElementById('sms-map-search-input');
      if (input && input.value) {
        this.setLocationFromSearch(input.value);
      }
      input.value = '';
    }

    maps.prototype.setNEBound = function(lat,lng) {
      this.NEBound = new gMaps.LatLng(lat,lng);
    }

    maps.prototype.setSWBound = function(lat,lng) {
      this.SWBound = new gMaps.LatLng(lat,lng);
    }

    maps.prototype.setLocationFromSearch = function(address) {
      var t = this,
      ne = t.NEBound || new gMaps.LatLng("42.58615975501869","-86.83601074218751"),
      sw = t.SWBound || new gMaps.LatLng("41.43521887122582","-88.30268554687501");
      
      t.geocoder.geocode({
        address: address,
        bounds: new gMaps.LatLngBounds(sw,ne),
        country: ".us"
      }, function(results, status) {
        t.placeMarker.call(t, (t.currentLocation = t.getLocation(null, results[0], t.getDefaultRadius())));
      });
    }

    maps.prototype.placeMarker = function(location) {
      if (this.currentMarker) {
        this.currentMarker.remove();
      }
      if (this.canAdd) {
        this.currentMarker = new this.marker(this.map, location);
      }
    }
  
    maps.prototype.removeMarker = function(marker) {
      var m = marker || this.currentMarker;
      if (m) {
        if (m.id) {
          this.removePreexistingLocation(m.id)
        }
        m.remove();
      }
    }
  
    maps.prototype.removePreexistingLocation = function(id) {
      if (this.removalsList) {
        var locationHTML = "";
        locationHTML += '<input type="hidden" name="' + this.objectName + '[id]" value="' + id + '">';
        locationHTML += '<input type="hidden" name="' + this.objectName + '[_delete]" value="1">';
        this.removalsList.innerHTML += locationHTML;
      }
    }
    maps.prototype.removeLocation = function(position) {
      var listItem = document.getElementById('sms-location-' + position);
      var marker = this.markers[position];
      if (listItem) {
        listItem.parentNode.removeChild(listItem);
      }
      this.removeMarker(marker);
    }
  
    maps.prototype.addLocation = function(location) {
      location = location || maps.currentMap.currentLocation;
      var t = this
      var listLength = t.locations;
      if (t.locationsList) {
        t.locationsList  = document.getElementById(t.locationsList.id);
        var li = document.createElement('li');
        var locationHTML = '<div class="sms-active-location-element">';
        locationHTML += '<div class="sms-active-location-remove">';
        locationHTML += '<a class="sms-location-remove" href="#" onclick="smsDeals.Maps.currentMap.removeLocation(' + listLength + '); return false;"><img src="/images/close.png" /></a>';
        locationHTML += '</div>';
        if (t.currentMarker.id) {
          locationHTML += '<input type="hidden" name="' + t.objectName + '[id]" value="' + t.currentMarker.id + '">';
        }
        locationHTML += '<input type="text" class="sms-location-name" name="' + t.objectName + '[name]" id="sms-location-name-' + listLength + '" onkeyup="smsDeals.Maps.currentMap.updateAddress(this,' + listLength + ');" value="' + location.formattedAddress + '" />';
        locationHTML += '</div>';
        if (t.usesRadius) {
          locationHTML += '<div>';
          locationHTML += '<label for="sms-location-radius-' + listLength + '">Radius:</label> ';
          locationHTML += '<select name="' + t.objectName + '[radius]" id="sms-location-radius-' + listLength + '" size="1" onchange="smsDeals.Maps.currentMap.updateRadius(this,' + listLength + ');">';
          for (var i=1; i<=5; i++) {
            locationHTML += '<option value="' + i + '"' + (i == location.radius ? 'selected="selected"' : '') + '>' + i + '</option>';
          }
          locationHTML += '</select> miles';
          locationHTML += '</div>';
        }
        locationHTML += '<input type="hidden" name="' + t.objectName + '[lat]" value="' + location.lat + '" />';
        locationHTML += '<input type="hidden" name="' + t.objectName + '[lng]" value="' + location.lng + '" />';
        locationHTML += '</div>';
        li.innerHTML = locationHTML;
        li.id = 'sms-location-' + listLength;
        t.locationsList.appendChild(li);
      }
      t.markers[listLength] = t.currentMarker;
      if (t.currentMarker && !t.currentMarker.confirmedLocation) t.currentMarker.setConfirmedLocationMarker(true);
      t.currentMarker = null;
      t.locations++;
    }
  
    maps.prototype.cancelAddLocation = function() {
      this.currentMarker.remove();
      this.currentMarker = null;
    }
  
    maps.prototype.updateAddress = function(t, position) {
      this.markers[position].updateAddress(t.value);
    }

    maps.prototype.updateRadius = function(t, position) {
      this.markers[position].updateRadius(t.value);
    }
  
    maps.prototype.location = function Location(location, result, radius) {
      var t = this;
      var valid = t.validLocation = !!result;
      if (!location && valid) {
        location = result.geometry.location;
      }
      if (location) {
        t.location = location;
        t.lat = location.lat();
        t.lng = location.lng();
      }
      t.radius = radius;
      t.formattedAddress = result ? result.formatted_address.replace(/, USA$/, '') : 'Invalid location.';
    }
  
    maps.prototype.marker = function Marker(map, location, confirmedLocation, id) {
      var t = this;
      var item = t.item = new gMaps.Marker({
        position: location.location, 
        map: map
      });
      var infoWindow = t.infoWindow = new gMaps.InfoWindow({
        content: getInfoWindowContent(location.formattedAddress, location.validLocation)
      });
      var radiusMarker;
      itemEvents = {};
      t.confirmedLocation = confirmedLocation;
      if (confirmedLocation) {
        setConfirmedLocationMarker(true);
      } else {
        openInfoWindow();
      }
      t.id = id;
      t.location = location;
    
      function openInfoWindow() {
        infoWindow.open(map, item);
      }
      function closeInfoWindow() {
        infoWindow.close();
      }
      t.closeInfoWindow = closeInfoWindow;
      function remove() {
        closeInfoWindow();
        item.setMap();
        if (radiusMarker) radiusMarker.setMap();
      }
      t.remove = remove;
      function setInfoWindowControls(hasControls) {
        infoWindow.content = getInfoWindowContent(location.formattedAddress, hasControls);
      }
      function getInfoWindowContent(message, showControls) {
        return '<div class="sms-map-infoWindow"><span class="sms-map-infoWindow-message">' + message + '</span>' + (showControls ? '<div class="sms-map-infoWindow-controls"><input type="submit" value="Add Location" onclick="smsDeals.Maps.currentMap.addLocation(); return false;" /> <input type="submit" value="Cancel" onclick="smsDeals.Maps.currentMap.cancelAddLocation();" /></div>' : '') + '</div>';
      }
      function setConfirmedLocationMarker(confirmedLoc) {
        if (confirmedLoc) {
          setRadiusMarker();
          setInfoWindowControls(false);
          itemEvents.mouseover = gMaps.event.addListener(item, 'mouseover', function() { 
            openInfoWindow(); 
          });
          itemEvents.mouseout = gMaps.event.addListener(item, 'mouseout', function() { 
            closeInfoWindow();
          });
          gMaps.event.trigger(item, 'mouseout');
        }
      }
      t.setConfirmedLocationMarker = setConfirmedLocationMarker;
      function setRadiusMarker() {
        var dst = location.radius / (10800 / Math.PI),
        toRadians = Math.PI / 180,
        toDegrees = 180 / Math.PI,
        lat = location.lat * toRadians,
        lng = location.lng * toRadians,
        points = [];
        function mod(x, y) {
          return x - y * Math.floor(x / y);
        }
        function sphericalPointByDirectionAndDistance(dir) {
          dir = dir * toRadians;
          var lat1 = Math.asin(Math.sin(lat) * Math.cos(dst) + Math.cos(lat) * Math.sin(dst) * Math.cos(dir)),
          lng1 = mod(lng - Math.atan2(Math.sin(dir) * Math.sin(dst) * Math.cos(lat), Math.cos(dst) - Math.sin(lat) * Math.sin(lat1)) + Math.PI, 2 * Math.PI) - Math.PI;
          return {lat: lat1 * toDegrees, lng: lng1 * toDegrees};
        }
        for (var i = 0; i < 180; i++) {
          var loc = sphericalPointByDirectionAndDistance(i * 2);
          points.push(new gMaps.LatLng(loc.lat, loc.lng));
        }
        if (radiusMarker) {
          radiusMarker.setMap();
        }
        radiusMarker = new gMaps.Polygon({
           paths: points,
           strokeColor: '#FF0000',
           strokeOpacity: 0.8,
           strokeWeight: 2,
           fillColor: '#FF0000',
           fillOpacity: 0.35
        });
        radiusMarker.setMap(map);
      }
      function getRadiusMarkerPaths() {
        return radiusMarker.getPaths();
      }
      this.getRadiusMarkerPaths = getRadiusMarkerPaths;
      function updateAddress(address) {
        location.formattedAddress = address;
        setInfoWindowControls(false);
      }
      this.updateAddress = updateAddress;
      function updateRadius(radius) {
        if (radius) radius = parseFloat(radius);
        if (radius && location.radius != radius) {
          location.radius = radius
          setRadiusMarker();
        }
      }
      this.updateRadius = updateRadius;
    };
  
    maps.subscriberMarker = maps.prototype.subscriberMarker = function SubscriberMarker(map, location) {
      var t = this;
      var item = t.item = new gMaps.Marker({
        position: location.location, 
        map: map,
        icon: maps.subscriberMarker.icon()
      });
      /*new gMaps.Polygon({
        path: [new gMaps.LatLng(location.lat+.002, location.lng-.002), new gMaps.LatLng(location.lat+.002, location.lng+.002), new gMaps.LatLng(location.lat-.002, location.lng+.002), new gMaps.LatLng(location.lat-.002, location.lng-.002), new gMaps.LatLng(location.lat+.002, location.lng-.002)],
        strokeColor: '#00FF00',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#00FF00',
        fillOpacity: 0.3
      });*/
      item.setMap(map);
      t.location = location;
    };
  
    maps.subscriberMarker.icon = function() {
      var size = new gMaps.Size(16, 16);
      var anchor = new gMaps.Point(7, 7);
      var markerImage = new gMaps.MarkerImage('/images/subscriberIcon.png', size, null, anchor);
      maps.subscriberMarker.icon = function() {
        return markerImage;
      }
      return markerImage;
    };
  }
})();

var smsDeals = window.smsDeals || {};

(function() {
  smsDeals.utils = smsDeals.utils || {};
  smsDeals.utils.fadeText = function() {
    for(var i = 0,aLen = arguments.length;i<aLen;i++) {
      if($(arguments[i])) {
        var that = $(arguments[i]);
        new Effect.Highlight(that)
        setTimeout(function() {new Effect.Fade(that);},25000);
      }
    }
  }
  smsDeals.utils.sameHeight = function() {
    var maxHeight = 0, currentHeight = 0;
    for(var i = 0,aLen = arguments.length;i<aLen;i++) {
      if($(arguments[i])) {
        var el = $(arguments[i]);
        currentHeight = parseInt(el.offsetHeight) - parseInt(el.getStyle('paddingTop'))- parseInt(el.getStyle('paddingBottom'));
        if(currentHeight > maxHeight) {
          maxHeight = currentHeight;
        }
      }
    }
    for(var i = 0,aLen = arguments.length;i<aLen;i++) {
      if($(arguments[i])) {
        $(arguments[i]).setStyle({height : maxHeight+'px'});
      }
    }
  }
  smsDeals.utils.deal_text_observe = function(area, chars_left_area) {
    $(area).observe('keyup', function(){smsDeals.utils.deal_text_observer(area, chars_left_area)});
    $(area).observe('keydown', function(){smsDeals.utils.deal_text_observer(area, chars_left_area)});
    smsDeals.utils.deal_text_observer(area, chars_left_area);
  }
  
  smsDeals.utils.deal_text_observer = function (area, chars_left_area) {
    var n = 93 - $(area).value.length
    c = $(chars_left_area),
    l = c.cloneNode(false);
    if (n >= 0) {
        l.innerHTML = "Remaining characters: " + n
      l.removeClassName("warning");
    } else {
      l.innerHTML =  "You have entered " + (-n) + " too many characters";
      l.addClassName("warning");
    }    
      c.parentNode.replaceChild(l, c);
  }
})();

var smsDeals = window.smsDeals || {};

(function() {
  
  smsDeals.deal = smsDeals.deal || {};
  
  smsDeals.deal.cache = [];
  
  smsDeals.deal.show_pending_deal = function(obj) {
    if(obj.hasClassName &&  obj.hasClassName('hilite'))  {return false;}
    $$("#sms-pending-deal-list a").each(function(a){a.removeClassName('hilite')});
    obj.addClassName("hilite");
    $('sms-pending-deal').innerHTML = $('ajax-indicator').innerHTML;
    if(smsDeals.deal.cache[obj.id]) {
      $('sms-pending-deal').innerHTML = '';
      $('sms-pending-deal').insert(smsDeals.deal.cache[obj.id]);
    } else {
      new Ajax.Updater('sms-pending-deal', obj.href, {
        evalScripts: true,
        onComplete : function(response) {
          smsDeals.deal.cache[obj.id] = response.responseText;
        }
      });
    }
  }
  
  smsDeals.deal.enableButton = function (el) {
    el.parentNode.down('button[type=submit]').disabled = el.value.blank();
    el.parentNode.down('button[type=submit]').enabled = !el.value.blank();
  }
  
  smsDeals.deal.change_pending_deal = function (url, params) {
    $('pending_ajax_indicator').show();
    new Ajax.Request(url, {
      parameters: params,
      onComplete: function(response){$('pending_ajax_indicator').hide()},
      onError: function(response){
        $('ajax_feedback').innerHTML = "Failed!";
        new Effect.Highlight('ajax_feedback');
      },
      onSuccess: function(response){
        $('ajax_feedback').innerHTML = response.responseText;
        new Effect.Highlight('ajax_feedback');
        $('pending_deal_' + params.id).hide();
        $$('#sms-pending-controls a').each(function(a){a.hide();});
      }
    });
  }
})();