/* Minification failed. Returning unminified contents.
(1095,63-64): run-time error JS1195: Expected expression: >
(1095,79-80): run-time error JS1004: Expected ';': )
(1096,10-11): run-time error JS1195: Expected expression: )
(1097,7-8): run-time error JS1002: Syntax error: }
(1102,65-66): run-time error JS1195: Expected expression: >
(1102,81-82): run-time error JS1004: Expected ';': )
(1114,11-12): run-time error JS1002: Syntax error: }
(1118,67-68): run-time error JS1195: Expected expression: >
(1118,105-106): run-time error JS1004: Expected ';': )
(1121,50-51): run-time error JS1004: Expected ';': {
(1141,6-7): run-time error JS1195: Expected expression: )
(1144,37-38): run-time error JS1195: Expected expression: )
(1144,39-40): run-time error JS1004: Expected ';': {
(1888,3-4): run-time error JS1002: Syntax error: }
(1890,26-27): run-time error JS1195: Expected expression: )
(1890,28-29): run-time error JS1004: Expected ';': {
(1898,3-20): run-time error JS1018: 'return' statement outside of function: return sameOrigin
 */
/**
 * @name InfoBox
 * @version 1.0 [January 11, 2010]
 * @author Gary Little (inspired by proof-of-concept code from Pamela Fox of Google)
 * @copyright Copyright 2010 Gary Little [gary at luxcentral.com]
 * @fileoverview InfoBox extends the Google Maps API v3 <tt>OverlayView</tt> class.
 *  <p>
 *  An InfoBox behaves like a <tt>google.maps.InfoWindow</tt>, but it supports several
 *  additional properties for advanced styling. An InfoBox can also be used as a map label.
 *  <p>
 *  An InfoBox also fires the same events as a <tt>google.maps.InfoWindow</tt>.
 *  <p>
 *  Browsers tested:
 *  <p>
 *  Mac -- Safari (4.0.4), Firefox (3.6), Opera (10.10), Chrome (4.0.249.43), OmniWeb (5.10.1)
 *  <br>
 *  Win -- Safari, Firefox, Opera, Chrome (3.0.195.38), Internet Explorer (8.0.6001.18702)
 *  <br>
 *  iPod Touch/iPhone -- Safari (3.1.2)
 */

/*!
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*jslint browser:true */
/*global google */

/**
 * @name InfoBoxOptions
 * @class This class represents the optional parameter passed to the {@link InfoBox} constructor.
 * @property {string|Node} content The content to display in the InfoBox (plain text or HTML).
 * @property {boolean} disableAutoPan Disable auto-pan on <tt>open</tt> (default is <tt>false</tt>).
 * @property {number} maxWidth The maximum width (in pixels) of the InfoBox. Set to 0 if no maximum.
 * @property {Size} pixelOffset The offset (in pixels) from the top left corner of the InfoBox
 *  to the map pixel corresponding to <tt>position</tt>.
 * @property {LatLng} position The geographic location at which to display the InfoBox.
 * @property {number} zIndex The CSS z-index style value for the InfoBox.
 *  Note: This value overrides a zIndex setting specified in the <tt>boxStyle</tt> property.
 * @property {Object} boxStyle An object literal with CSS style settings for the InfoBox container.
 *  Note: Border widths must be specified in px units because of an MSIE limitation.
 * @property {string} closeBoxMargin The CSS margin style value for the close box.
 *  The default is "2px" (a 2-pixel margin on all sides).
 * @property {string} closeBoxURL The URL of the image representing the close box.
 *  Note: The default is the URL for Google's standard close box.
 *  Set this property to "" if no close box is required.
 * @property {Size} infoBoxClearance Minimum offset (in pixels) from the InfoBox to the
 *  map edge after an auto-pan.
 * @property {boolean} isHidden Hide the InfoBox on <tt>open</tt> (default is <tt>false</tt>).
 * @property {string} pane The pane where the InfoBox is to appear (default is "floatPane").
 *  Set the pane to "mapPane" if the InfoBox is being used as a map label.
 *  Valid pane names are the property names for the <tt>google.maps.MapPanes</tt> object.
 */

/**
 * Creates an InfoBox with the options specified in {@link InfoBoxOptions}.
 *  Call <tt>InfoBox.open</tt> to add the box to the map.
 * @constructor
 * @param {InfoBoxOptions} [opt_opts]
 */
function InfoBox(opt_opts) {

  opt_opts = opt_opts || {};

  google.maps.OverlayView.apply(this, arguments);

  // Standard options (in common with google.maps.InfoWindow):
  //
  this.content_ = opt_opts.content || "";
  this.disableAutoPan_ = opt_opts.disableAutoPan || false;
  this.maxWidth_ = opt_opts.maxWidth || 0;
  this.pixelOffset_ = opt_opts.pixelOffset || new google.maps.Size(0, 0);
  this.position_ = opt_opts.position || new google.maps.LatLng(0, 0);
  this.zIndex_ = opt_opts.zIndex || null;

  // Additional options (unique to InfoBox):
  //
  this.boxStyle_ = opt_opts.boxStyle || {};
  this.closeBoxMargin_ = opt_opts.closeBoxMargin || "2px";
  this.closeBoxURL_ = opt_opts.closeBoxURL || "http://www.google.com/intl/en_us/mapfiles/close.gif";
  if (opt_opts.closeBoxURL === "") {
    this.closeBoxURL_ = "";
  }
  this.infoBoxClearance_ = opt_opts.infoBoxClearance || new google.maps.Size(1, 1);
  this.isHidden_ = opt_opts.isHidden || false;
  this.pane_ = opt_opts.pane || "floatPane";

  this.div_ = null;
  this.closeListener_ = null;
  this.fixedWidthSet_ = null;
}

/* InfoBox extends OverlayView in the Google Maps API v3.
 */
InfoBox.prototype = new google.maps.OverlayView();

/**
 * Creates the DIV representing the InfoBox.
 * @private
 */
InfoBox.prototype.createInfoBoxDiv_ = function () {

  var bw;

  if (!this.div_) {

    this.div_ = document.createElement("div");

    this.setBoxStyle_();

    // Apply required styles:
    //
    this.div_.style.position = "absolute";
    this.div_.style.visibility = 'hidden';
    if (this.zIndex_ !== null) {

      this.div_.style.zIndex = this.zIndex_;
    }

    this.div_.innerHTML = this.getCloseBoxImg_() + this.content_;

    // Add the InfoBox DIV to the DOM
    this.getPanes()[this.pane_].appendChild(this.div_);

    this.addClickHandler_();

    if (this.div_.style.width) {

      this.fixedWidthSet_ = true;

    } else {

      if (this.maxWidth_ !== 0 && this.div_.offsetWidth > this.maxWidth_) {

        this.div_.style.width = this.maxWidth_;
        this.div_.style.overflow = "auto";
        this.fixedWidthSet_ = true;

      } else { // The following code is needed to overcome problems with MSIE

        bw = this.getBoxWidths_();

        this.div_.style.width = (this.div_.offsetWidth - bw.left - bw.right) + "px";
        this.fixedWidthSet_ = false;
      }
    }

    this.panBox_(this.disableAutoPan_);

    /**
     * This event is fired when the DIV containing the InfoBox's content is attached to the DOM.
     * @name InfoBox#domready
     * @event
     */
    google.maps.event.trigger(this, "domready");

  }
};

/**
 * Returns the HTML <IMG> tag for the close box.
 * @private
 */
InfoBox.prototype.getCloseBoxImg_ = function () {

  var img = "";

  if (this.closeBoxURL_ !== "") {

    img  = "<img";
    img += " src='" + this.closeBoxURL_ + "'";
    img += " align=right"; // Do this because Opera chokes on style='float: right;'
    img += " style='";
    img += " position: relative;"; // Required by MSIE
    img += " cursor: pointer;";
    img += " margin: " + this.closeBoxMargin_ + ";";
    img += "'>";
  }

  return img;
};

/**
 * Adds the click handler to the InfoBox close box.
 * @private
 */
InfoBox.prototype.addClickHandler_ = function () {

  var closeBox;

  if (this.closeBoxURL_ !== "") {

    closeBox = this.div_.firstChild;
    this.closeListener_ = google.maps.event.addDomListener(closeBox, 'click', this.getCloseClickHandler_());

  } else {

    this.closeListener_ = null;
  }
};

/**
 * Returns the function to call when the user clicks the close box of an InfoBox.
 * @private
 */
InfoBox.prototype.getCloseClickHandler_ = function () {

  var me = this;

  return function () {

    me.close();

    /**
     * This event is fired when the InfoBox's close box is clicked.
     * @name InfoBox#closeclick
     * @event
     */
    google.maps.event.trigger(me, "closeclick");
  };
};

/**
 * Pans the map so that the InfoBox appears entirely within the map's visible area.
 * @private
 */
InfoBox.prototype.panBox_ = function (disablePan) {

  if (!disablePan) {

    var map = this.getMap();
    var bounds = map.getBounds();

    // The degrees per pixel
    var mapDiv = map.getDiv();
    var mapWidth = mapDiv.offsetWidth;
    var mapHeight = mapDiv.offsetHeight;
    var boundsSpan = bounds.toSpan();
    var longSpan = boundsSpan.lng();
    var latSpan = boundsSpan.lat();
    var degPixelX = longSpan / mapWidth;
    var degPixelY = latSpan / mapHeight;

    // The bounds of the map
    var mapWestLng = bounds.getSouthWest().lng();
    var mapEastLng = bounds.getNorthEast().lng();
    var mapNorthLat = bounds.getNorthEast().lat();
    var mapSouthLat = bounds.getSouthWest().lat();

    // The bounds of the box
    var position = this.position_;
    var iwOffsetX = this.pixelOffset_.width;
    var iwOffsetY = this.pixelOffset_.height;
    var padX = this.infoBoxClearance_.width;
    var padY = this.infoBoxClearance_.height;
    var iwWestLng = position.lng() + (iwOffsetX - padX) * degPixelX;
    var iwEastLng = position.lng() + (iwOffsetX + this.div_.offsetWidth + padX) * degPixelX;
    var iwNorthLat = position.lat() - (iwOffsetY - padY) * degPixelY;
    var iwSouthLat = position.lat() - (iwOffsetY + this.div_.offsetHeight + padY) * degPixelY;

    // Calculate center shift
    var shiftLng =
      (iwWestLng < mapWestLng ? mapWestLng - iwWestLng : 0) +
      (iwEastLng > mapEastLng ? mapEastLng - iwEastLng : 0);
    var shiftLat =
      (iwNorthLat > mapNorthLat ? mapNorthLat - iwNorthLat : 0) +
      (iwSouthLat < mapSouthLat ? mapSouthLat - iwSouthLat : 0);

    if (!(shiftLat === 0 && shiftLng === 0)) {

      // Move the map to the new shifted center.
      //
      var c = map.getCenter();
      map.setCenter(new google.maps.LatLng(c.lat() - shiftLat, c.lng() - shiftLng));
    }
  }
};

/**
 * Sets the style of the InfoBox.
 * @private
 */
InfoBox.prototype.setBoxStyle_ = function () {

  var i;

  var boxStyle = this.boxStyle_;

  for (i in boxStyle) {

    if (boxStyle.hasOwnProperty(i)) {

      this.div_.style[i] = boxStyle[i];
    }
  }

  // Fix up opacity style for benefit of MSIE:
  //
  if (typeof this.div_.style.opacity !== "undefined") {

    this.div_.style.filter = "alpha(opacity=" + (this.div_.style.opacity * 100) + ")";
  }
};

/**
 * Get the widths of the borders of the InfoBox.
 * @private
 * @return {Object} widths object (top, bottom left, right)
 */
InfoBox.prototype.getBoxWidths_ = function () {

  var computedStyle;
  var bw = {top: 0, bottom: 0, left: 0, right: 0};
  var box = this.div_;

  if (document.defaultView && document.defaultView.getComputedStyle) {

    computedStyle = box.ownerDocument.defaultView.getComputedStyle(box, "");

    if (computedStyle) {

      // The computed styles are always in pixel units (good!)
      bw.top = parseInt(computedStyle.borderTopWidth, 10) || 0;
      bw.bottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
      bw.left = parseInt(computedStyle.borderLeftWidth, 10) || 0;
      bw.right = parseInt(computedStyle.borderRightWidth, 10) || 0;
    }

  } else if (document.documentElement.currentStyle) { // MSIE

    if (box.currentStyle) {

      // The current styles may not be in pixel units, but assume they are (bad!)
      bw.top = parseInt(box.currentStyle.borderTopWidth, 10) || 0;
      bw.bottom = parseInt(box.currentStyle.borderBottomWidth, 10) || 0;
      bw.left = parseInt(box.currentStyle.borderLeftWidth, 10) || 0;
      bw.right = parseInt(box.currentStyle.borderRightWidth, 10) || 0;
    }
  }

  return bw;
};

/**
 * Invoked when <tt>close</tt> is called. Do not call it directly.
 */
InfoBox.prototype.onRemove = function () {

  if (this.div_) {

    this.div_.parentNode.removeChild(this.div_);
    this.div_ = null;
  }
};

/**
 * Draws the InfoBox based on the current map projection and zoom level.
 */
InfoBox.prototype.draw = function () {

  this.createInfoBoxDiv_();

  var pixPosition = this.getProjection().fromLatLngToDivPixel(this.position_);

  this.div_.style.left = (pixPosition.x + this.pixelOffset_.width) + "px";
  this.div_.style.top = (pixPosition.y + this.pixelOffset_.height - 20) + "px";

  var newPos = (pixPosition.y + this.pixelOffset_.height);

  jQuery(this.div_).css({opacity: 0, visibility: "hidden", top: this.div_.style.top});

  if (this.isHidden_) {
    //this.div_.style.visibility = 'hidden';
    jQuery(this.div_).css({opacity: 0, visibility: "hidden", top: this.div_.style.top});

  } else {
    //this.div_.style.visibility = "visible";
    jQuery(this.div_).css({visibility: "visible"}).animate({opacity: 1, top: newPos}, 200);
  }
};

/**
 * Sets the options for the InfoBox. Note that changes to the <tt>maxWidth</tt>,
 *  <tt>closeBoxMargin</tt>, and <tt>closeBoxURL</tt> properties have no affect
 *  until the current InfoBox is <tt>close</tt>d and a new one is <tt>open</tt>ed.
 * @param {InfoBoxOptions} opt_opts
 */
InfoBox.prototype.setOptions = function (opt_opts) {

  if (typeof opt_opts.boxStyle !== "undefined") { // Must be first

    this.boxStyle_ = opt_opts.boxStyle;
    this.setBoxStyle_();
  }
  if (typeof opt_opts.content !== "undefined") {

    this.setContent(opt_opts.content);
  }
  if (typeof opt_opts.disableAutoPan !== "undefined") {

    this.disableAutoPan_ = opt_opts.disableAutoPan;
  }
  if (typeof opt_opts.maxWidth !== "undefined") {

    this.maxWidth_ = opt_opts.maxWidth;
  }
  if (typeof opt_opts.pixelOffset !== "undefined") {

    this.pixelOffset_ = opt_opts.pixelOffset;
  }
  if (typeof opt_opts.position !== "undefined") {

    this.setPosition(opt_opts.position);
  }
  if (typeof opt_opts.zIndex !== "undefined") {

    this.setZIndex(opt_opts.zIndex);
  }
  if (typeof opt_opts.closeBoxMargin !== "undefined") {

    this.closeBoxMargin_ = opt_opts.closeBoxMargin;
  }
  if (typeof opt_opts.closeBoxURL !== "undefined") {

    this.closeBoxURL_ = opt_opts.closeBoxURL;
  }
  if (typeof opt_opts.infoBoxClearance !== "undefined") {

    this.infoBoxClearance_ = opt_opts.infoBoxClearance;
  }
  if (typeof opt_opts.isHidden !== "undefined") {

    this.isHidden_ = opt_opts.isHidden;
  }

  if (this.div_) {

    this.draw();
  }
};

/**
 * Sets the content of the InfoBox.
 *  The content can be plain text or HTML.
 * @param {string} content
 */
InfoBox.prototype.setContent = function (content) {

  this.content_ = content;

  if (this.div_) {

    if (this.closeListener_) {

      google.maps.event.removeListener(this.closeListener_);
      this.closeListener_ = null;
    }

    // Odd code required to make things work with MSIE.
    //
    if (!this.fixedWidthSet_) {

      this.div_.style.width = "";
    }

    this.div_.innerHTML = this.getCloseBoxImg_() + content;

    // Perverse code required to make things work with MSIE.
    // (Ensures the close box does, in fact, float to the right.)
    //
    if (!this.fixedWidthSet_) {

      this.div_.style.width = this.div_.offsetWidth + "px";
      this.div_.innerHTML = this.getCloseBoxImg_() + content;
    }

    this.addClickHandler_();
  }

  /**
   * This event is fired when the content of the InfoBox changes.
   * @name InfoBox#content_changed
   * @event
   */
  google.maps.event.trigger(this, "content_changed");
};

/**
 * Sets the geographic location of the InfoBox.
 * @param {LatLng} latlng
 */
InfoBox.prototype.setPosition = function (latlng) {

  this.position_ = latlng;

  if (this.div_) {

    this.draw();
  }

  /**
   * This event is fired when the position of the InfoBox changes.
   * @name InfoBox#position_changed
   * @event
   */
  google.maps.event.trigger(this, "position_changed");
};

/**
 * Sets the zIndex style for the InfoBox.
 * @param {number} index
 */
InfoBox.prototype.setZIndex = function (index) {

  this.zIndex_ = index;

  if (this.div_) {

    this.div_.style.zIndex = index;
  }

  /**
   * This event is fired when the zIndex of the InfoBox changes.
   * @name InfoBox#zindex_changed
   * @event
   */
  google.maps.event.trigger(this, "zindex_changed");
};

/**
 * Returns the content of the InfoBox.
 * @returns {string}
 */
InfoBox.prototype.getContent = function () {

  return this.content_;
};

/**
 * Returns the geographic location of the InfoBox.
 * @returns {LatLng}
 */
InfoBox.prototype.getPosition = function () {

  return this.position_;
};

/**
 * Returns the zIndex for the InfoBox.
 * @returns {number}
 */
InfoBox.prototype.getZIndex = function () {

  return this.zIndex_;
};

/**
 * Shows the InfoBox.
 */
InfoBox.prototype.show = function () {

  this.isHidden_ = false;
  this.div_.style.visibility = "visible";
};

/**
 * Hides the InfoBox.
 */
InfoBox.prototype.hide = function () {

  this.isHidden_ = true;
  this.div_.style.visibility = "hidden";
};

/**
 * Adds the InfoBox to the specified map. If <tt>anchor</tt>
 *  (usually a <tt>google.maps.Marker</tt>) is specified, the position
 *  of the InfoBox is set to the position of the <tt>anchor</tt>.
 * @param {Map} map
 * @param {MVCObject} [anchor]
 */
InfoBox.prototype.open = function (map, anchor) {

  if (anchor) {

    this.position_ = anchor.getPosition();
  }

  this.setMap(map);

  if (this.div_) {

    this.panBox_();
  }
};

/**
 * Removes the InfoBox from the map.
 */
InfoBox.prototype.close = function () {
  var self = this;

  if (this.closeListener_) {
    google.maps.event.removeListener(this.closeListener_);
    this.closeListener_ = null;
  }

  var pixPosition = this.getProjection().fromLatLngToDivPixel(this.position_);
  var newPos = (pixPosition.y + this.pixelOffset_.height - 20) + "px";

  jQuery(this.div_).animate({opacity: 0, top: newPos}, 200, function() {
      jQuery(self.div_).css({visibility: "hidden"});
      self.setMap(null);
  });
};;
var props = [
	{
		dealid: 1,
		dealtitle: 'An authentic Italian meal for two',
		dealimg: 'images/deal1.jpg',
		dealoff: '51% OFF',
		dealdetails: '$15 for $30 Worth of Southern Itialian Dinner for Two or More at Cucina Calandra',
		dealdesbold: 'Cucina Calandra',
		dealdessmall: 'Fairfield (16.9 miles)',
		dealthumbsup: '94% of 273 customers recommend0',
		position: {
			lat: 40.696047,
			lng: -73.997159
		},
		markerIcon: "marker-green.png",
		markerWidth: 23,
		markerHeight: 27
	},
	{
		dealid: 2,
		dealtitle: 'An authentic Italian meal for two',
		dealimg: 'images/deal2.jpg',
		dealoff: '52% OFF',
		dealdetails: '$15 for $30 Worth of Southern Itialian Dinner for Two or More at Cucina Calandra',
		dealdesbold: 'Cucina Calandra',
		dealdessmall: 'Fairfield (16.9 miles)',
		dealthumbsup: '94% of 273 customers recommend0',
		position: {
			lat: 40.688042,
			lng: -73.996472
		},
		markerIcon: "marker-pink.png",
		markerWidth: 28,
		markerHeight: 40
	},
	{
		dealid: 3,
		dealtitle: 'An authentic Italian meal for two',
		dealimg: 'images/deal1.jpg',
		dealoff: '53% OFF',
		dealdetails: '$15 for $30 Worth of Southern Itialian Dinner for Two or More at Cucina Calandra',
		dealdesbold: 'Cucina Calandra',
		dealdessmall: 'Fairfield (16.9 miles)',
		dealthumbsup: '94% of 273 customers recommend0',
		position: {
			lat: 40.702620,
			lng: -73.989682
		},
		markerIcon: "marker-green.png",
		markerWidth: 23,
		markerHeight: 27
	},
	{
		dealid: 4,
		dealtitle: 'An authentic Italian meal for two',
		dealimg: 'images/deal2.jpg',
		dealoff: '54% OFF',
		dealdetails: '$15 for $30 Worth of Southern Itialian Dinner for Two or More at Cucina Calandra',
		dealdesbold: 'Cucina Calandra',
		dealdessmall: 'Fairfield (16.9 miles)',
		dealthumbsup: '94% of 273 customers recommend0',
		position: {
			lat: 40.694355,
			lng: -73.985229
		},
		markerIcon: "marker-pink.png",
		markerWidth: 28,
		markerHeight: 40
	},
	{
		dealid: 5,
		dealtitle: 'An authentic Italian meal for two',
		dealimg: 'images/deal1.jpg',
		dealoff: '55% OFF',
		dealdetails: '$15 for $30 Worth of Southern Itialian Dinner for Two or More at Cucina Calandra',
		dealdesbold: 'Cucina Calandra',
		dealdessmall: 'Fairfield (16.9 miles)',
		dealthumbsup: '94% of 273 customers recommend0',
		position: {
			lat: 40.686838,
			lng: -73.990078
		},
		markerIcon: "marker-green.png",
		markerWidth: 23,
		markerHeight: 27
	},
	{
		dealid: 6,
		dealtitle: 'An authentic Italian meal for two',
		dealimg: 'images/deal2.jpg',
		dealoff: '56% OFF',
		dealdetails: '$15 for $30 Worth of Southern Itialian Dinner for Two or More at Cucina Calandra',
		dealdesbold: 'Cucina Calandra',
		dealdessmall: 'Fairfield (16.9 miles)',
		dealthumbsup: '94% of 273 customers recommend0',
		position: {
			lat: 40.703686,
			lng: -73.982910
		},
		markerIcon: "marker-pink.png",
		markerWidth: 28,
		markerHeight: 40
	},
	{
		dealid: 7,
		dealtitle: 'An authentic Italian meal for two',
		dealimg: 'images/deal1.jpg',
		dealoff: '57% OFF',
		dealdetails: '$15 for $30 Worth of Southern Itialian Dinner for Two or More at Cucina Calandra',
		dealdesbold: 'Cucina Calandra',
		dealdessmall: 'Fairfield (16.9 miles)',
		dealthumbsup: '94% of 273 customers recommend0',
		position: {
			lat: 40.702189,
			lng: -73.995098
		},
		markerIcon: "marker-green.png",
		markerWidth: 23,
		markerHeight: 27
	},
	{
		dealid: 8,
		dealtitle: 'An authentic Italian meal for two',
		dealimg: 'images/deal2.jpg',
		dealoff: '58% OFF',
		dealdetails: '$15 for $30 Worth of Southern Itialian Dinner for Two or More at Cucina Calandra',
		dealdesbold: 'Cucina Calandra',
		dealdessmall: 'Fairfield (16.9 miles)',
		dealthumbsup: '94% of 273 customers recommend0',
		position: {
			lat: 40.694120,
			lng: -73.974413
		},
		markerIcon: "marker-green.png",
		markerWidth: 23,
		markerHeight: 27
	},
	{
		dealid: 9,
		dealtitle: 'An authentic Italian meal for two',
		dealimg: 'images/deal1.jpg',
		dealoff: '59% OFF',
		dealdetails: '$15 for $30 Worth of Southern Itialian Dinner for Two or More at Cucina Calandra',
		dealdesbold: 'Cucina Calandra',
		dealdessmall: 'Fairfield (16.9 miles)',
		dealthumbsup: '94% of 273 customers recommend0',
		position: {
			lat: 40.682665,
			lng: -73.000934
		},
		markerIcon: "marker-pink.png",
		markerWidth: 28,
		markerHeight: 40
	}];

var markers = [];

// custom infowindow object
var infobox = new InfoBox({
	disableAutoPan: false,
	maxWidth: 600,
	pixelOffset: new google.maps.Size(-101, -285),
	zIndex: null,
	boxStyle: {
		background: "url('/Images/AMaterial/infobox-bg.png') no-repeat",
		opacity: 1,
		width: "280px",
		height: "220px"
	},
	closeBoxMargin: "28px 26px 0px 0px",
	closeBoxURL: "",
	infoBoxClearance: new google.maps.Size(1, 1),
	pane: "floatPane",
	enableEventPropagation: false
});
var attinfobox = new InfoBox({
	disableAutoPan: false,
	maxWidth: 100,
	pixelOffset: new google.maps.Size(-20, -90),
	zIndex: null,
	boxStyle: {
		border: "1px solid black",
		background: "url('/Images/AMaterial/infobox-bg.png') no-repeat",
		opacity: 1,
		width: "100px",
		height: "50px"
	},
	closeBoxMargin: "28px 26px 0px 0px",
	closeBoxURL: "",
	infoBoxClearance: new google.maps.Size(1, 1),
	pane: "floatPane",
	enableEventPropagation: false
});

function createMap(lat, lng) {
	"use strict";

	// Custom options for map
	var options = {
		zoom: 14,
		scrollwheel: false,
		mapTypeId: 'Styled',
		disableDefaultUI: false,
		mapTypeControlOptions: {
			mapTypeIds: ['Styled']
		}
	};

	var styles = [{ "featureType": "administrative", "elementType": "labels.text.fill", "stylers": [{ "color": "#444444" }] }, { "featureType": "landscape", "elementType": "all", "stylers": [{ "color": "#f2f2f2" }] }, { "featureType": "poi", "elementType": "all", "stylers": [{ "visibility": "off" }] }, { "featureType": "road", "elementType": "all", "stylers": [{ "saturation": -100 }, { "lightness": 45 }] }, { "featureType": "road.highway", "elementType": "all", "stylers": [{ "visibility": "simplified" }] }, { "featureType": "road.arterial", "elementType": "labels.icon", "stylers": [{ "visibility": "off" }] }, { "featureType": "transit", "elementType": "all", "stylers": [{ "visibility": "off" }] }, { "featureType": "water", "elementType": "all", "stylers": [{ "color": "#46bcec" }, { "visibility": "on" }] }];

	var newMarker = null;

	// json for properties markers on map
	var obj = document.getElementById('mapView');
	var map = new google.maps.Map(obj, options);
	var styledMapType = new google.maps.StyledMapType(styles, {
		name: 'Styled'
	});

	map.mapTypes.set('Styled', styledMapType);
	map.setCenter(new google.maps.LatLng(lat, lng));
	map.setZoom(14);
	return map;
}

// function that adds the markers on map
function addDealMarkers(props, map) {
	"use strict";
	$.each(props, function (i, prop) {
		var latlng = new google.maps.LatLng(prop.position.lat, prop.position.lng);
		var marker = new google.maps.Marker({
			position: latlng,
			map: map,
			icon: new google.maps.MarkerImage(
					'/Images/AMaterial/' + prop.markerIcon,
					null,
					null,
					null,
					new google.maps.Size(prop.markerWidth, prop.markerHeight)
			),
			draggable: false,
			animation: google.maps.Animation.DROP,
		});
		var infoboxContent = '<div class="infoW">' +
					'<h3 class="infoHead">' + prop.dealtitle + '</h3>' +
					'<div class="infoContent">' +
																'<img class="propImg" src="' + prop.dealimg + '">' +
																'<div class="propTitle">' + prop.dealoff + '</div>' +
																'<div class="propAddress">' + prop.dealdetails + '</div>' +
														'</div>' +
														'<div class="clearfix"></div>' +
														'<div class="infoButtons">' +
																'<a onclick="addToCartMap(this, ' + prop.dealid + ')" class="addInfo">Add to Cart</a>' +
																'<a href="" class="viewInfo">Details</a>' +
														'</div>' +
												 '</div>';
		google.maps.event.addListener(marker, 'click', (function (marker, i) {
			return function () {
				infobox.setContent(infoboxContent);
				infobox.open(map, marker);
			}
		})(marker, i));

		$(document).on('click', '.addInfo', function () {
			infobox.open(null, null);
		});

		markers.push(marker);
	});
}

// function that adds the attendee markers on map
function addAttendeeMarkers(list, map) {
	"use strict";
	$.each(list, function (i, item) {
		var latlng = new google.maps.LatLng(item.Latitude, item.Longitude);
		var marker = new google.maps.Marker({
			position: latlng,
			map: map,
			icon: new google.maps.MarkerImage(
				'/Images/AMaterial/' + 'marker-pink-circle.png',
				null,
				null,
				null,
				new google.maps.Size(setIconHeight(item.AttendeeCount,20), setIconHeight(item.AttendeeCount,20))
			),
			draggable: false,
			animation: google.maps.Animation.DROP,
		});
		var infoboxContent = '<div class="attinfoW">' +
			'<div class="attinfoContent">' +
			'<a href="javascript:void(0)" class="tabclose" style="float:right;margin-top:5px;margin-right:5px;"><img style="height:10px;width:10px;" src="/Images/cross.png"/></a><br/>' + 
			'<div class="attcont" style="margin-left:5px;"><b>' + item.CityName + '</b><br>Attendee Count : '+ item.AttendeeCount +'</div>' +
			'</div>' +
			'</div>';
		google.maps.event.addListener(marker, 'click', (function (marker, i) {
			return function () {
				attinfobox.setContent(infoboxContent);
				attinfobox.open(map, marker);
			}
		})(marker, i));

		$(document).on('click', '.addInfo', function () {
			attinfobox.open(null, null);
		});
		$(document).on('click', '.tabclose', function () {
			attinfobox.close();
		});

		markers.push(marker);
	});
}
function setIconHeight(count,height) {
	if (count > 0)
		height = height + (count*2);
	if (height > 50)
		return 30;
	return height;
}

// Sets the map on all markers in the array.
function setMapOnAll(map) {
	for (var i = 0; i < markers.length; i++) {
		markers[i].setMap(map);
	}
}

// Removes the markers from the map, but keeps them in the array.
function clearMarkers() {
	setMapOnAll(null);
}

// Shows any markers currently in the array.
function showMarkers(map) {
	setMapOnAll(map);
}

// Deletes all markers in the array by removing references to them.
function deleteMarkers() {
	clearMarkers();
	markers = [];
}

// function that adds the markers on map
function addEventMarker(eventInfo, map) {
	"use strict";
	var latlng = new google.maps.LatLng(eventInfo.Latitude, eventInfo.Longitude);
	var marker = new google.maps.Marker({
		position: latlng,
		map: map,
		icon: new google.maps.MarkerImage(
				'/Images/AMaterial/marker-pink.png',
				null,
				null,
				null,
				new google.maps.Size(28, 40)
		),
		draggable: false,
		animation: google.maps.Animation.DROP,
	});
	var infoboxContent = '<div class="infoW">' +
				'<h3 class="infoHead">' + eventInfo.EventTitle + '</h3>' +
				'<div class="infoContent">' +
															'<img class="propImg" src="' + eventInfo.ImageUrl + '">' +
															'<div class="propTitle">' + eventInfo.Address + '</div>' +
															'<div class="propAddress">' + eventInfo.EventShortDesc + '</div>' +
													'</div>' +
													'<div class="clearfix"></div>' +
													'<div class="infoButtons">' +
															'<a href="' + eventInfo.EventUrl + '" class="viewInfo">Details</a>' +
													'</div>' +
											 '</div>';
	google.maps.event.addListener(marker, 'click', (function (marker) {
		return function () {
			infobox.setContent(infoboxContent);
			infobox.open(map, marker);
		}
	})(marker));

	markers.push(marker);
};
eventComboApp.controller('ViewEventController', ['$scope', '$http', '$window', '$attrs', 'eventInfoService', 'broadcastService', 'accountService', '$mdDialog', '$mdToast', '$location', '$sce',
  function ($scope, $http, $window, $attrs, eventInfoService, broadcastService, accountService, $mdDialog, $mdToast, $location, $sce) {
    $scope.pageURL = window.location.href;
    $scope.eventInfo = {};
    $scope.waitlistId = 0;
    if (typeof waitlistId !== "undefined")
      $scope.waitlistId = waitlistId;
    $scope.waitlistInfo = {};
    $scope.eventJoinWaitListTicketQty = 0;
    $scope.selectedDate = {};
    $scope.selectedVenue = {};
    $scope.selectedVenueName = "";
    $scope.selectedTickets = [];
    $scope.allScheduleList = [];
    $scope.Teams = [];
    $scope.popVEShareWithFriends = false;
    $scope.popVEOrganizerMessage = false;
    $scope.popVEPassword = false;
    $scope.mapLoaded = false;
    $scope.showLoader = true;
    $scope.VEMessage = {
      Email: '',
      Name: '',
      Phone: '',
      Message: '',
      EventId: 0
    }
    $scope.FacebookConnect = {
      Connected: false,
      FacebookUser: {},
      FacebookFriends: []
    };

    $scope.eventRoles = [];

    if (!$attrs.eventid) throw new Error("No event ID defined");

    if ($attrs.eventid === 29576) {
      !function (f, b, e, v, n, t, s) {
        if (f.fbq) return; n = f.fbq = function () {
          n.callMethod ?
            n.callMethod.apply(n, arguments) : n.queue.push(arguments)
        };
        if (!f._fbq) f._fbq = n; n.push = n; n.loaded = !0; n.version = '2.0';
        n.queue = []; t = b.createElement(e); t.async = !0;
        t.src = v; s = b.getElementsByTagName(e)[0];
        s.parentNode.insertBefore(t, s)
      }(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
      fbq('init', '137748770207602');
      fbq('track', 'PageView');
    }

    $scope.toggleFAQsAns = function (index) {
      $scope.eventInfo.EventFAQList[index].showAns = !$scope.eventInfo.EventFAQList[index].showAns;
    };

    var getPriceText = function (amount) {
      return amount > 0 ? $scope.eventInfo.Currency.SymbolAsString + amount.toFixed(2) : $scope.eventInfo.Currency.SymbolAsString + "0";
    }

    $scope.uCanTrust = function (string) {
      return $sce.trustAsHtml(string);
    }

    $scope.isUSDCurrency = function () {
      return !$scope.eventInfo.Currency || $scope.eventInfo.Currency.ShortName === "USD";
    }

    $scope.getCurrencyShortName = function () {
      return $scope.isUSDCurrency() ? "" : "(" + $scope.eventInfo.Currency.ShortName + ")";
    }

    $scope.isVenueSelectAvailable = function () {
      return $scope.eventInfo.AddressList && $scope.eventInfo.AddressList.length > 1 && $scope.eventInfo.AllowSelectVenue;
    }

    $scope.isDateSelectAvailable = function () {
      return $scope.eventInfo.AvailableDates && $scope.eventInfo.AvailableDates.length > 1 && $scope.eventInfo.AllowSelectDate;
    }
    $scope.checkIsArray = function (arr) {
      return Array.isArray(arr);
    };

    $scope.filterTickets = function (eventRoleId) {
      if (!$scope.isVenueSelectAvailable() && !$scope.isDateSelectAvailable()) {
        $scope.selectedTickets = $scope.eventInfo.Tickets;
        angular.forEach($scope.selectedTickets, function (ticket) {
          ticket.ScheduleList = ticket.ScheduleList.filter(a => a.AllowOnEvent);
        });
      }
      else {
        $scope.selectedTickets = [];
        angular.forEach($scope.eventInfo.Tickets,
          function (ticket) {
            ticket.ScheduleList = ticket.ScheduleList.filter(a => a.AllowOnEvent)
            if ((!$scope.isDateSelectAvailable() || ticket.StartDate.getTime() === $scope.selectedDate.Date.getTime()) &&
              (!$scope.isVenueSelectAvailable() || ticket.Address.AddressId === $scope.selectedVenue.AddressId)) {
              $scope.selectedTickets.push(ticket);
            }
            if (ticket.TicketTypeId === 3) {
              ticket.Amount = 0;
              $scope.onPriceBlur(ticket);
            } else {
              ticket.Quantity = 0;
              $scope.onPriceChange();
            }
          });
      }

      if (eventRoleId)
        $scope.selectedTickets = $scope.selectedTickets.filter(x => x.EventRoleIds.includes(eventRoleId));
    }

    $scope.$on('EventInfoLoaded', function (val) {
      $scope.eventInfo = eventInfoService.getEventInfo();
      $scope.waitlistInfo = eventInfoService.getWaitlistInfo();
      if ($attrs.canceltickets && !isToRelod) {
        $scope.showCancelReleaseTicket(true);
      }
      $scope.selectedVenue = $scope.eventInfo.AddressList[0];
      if ($scope.isVenueSelectAvailable())
        $scope.selectedVenueName = $scope.selectedVenue.VenueName;
      else
        $scope.selectedVenueName = $scope.eventInfo.AddressList.map(function (elem) {
          return elem.VenueName;
        }).join(', ');
      $scope.selectedDate = $scope.eventInfo.AvailableDates[0];
      $scope.eventInfo.Tickets.forEach(function (ticket, i, arr) {
        ticket.PriceText = getPriceText(ticket.Amount);
      });
      $scope.filterTickets();
      $scope.eventInfoLoaded = true;
      $scope.showLoader = false;
    });


    $scope.loadEventmap = function () {
      deleteMarkers();
      if ($scope.eventInfo.Latitude) {
        $scope.map = createMap(40.6984237, -73.9890044);
        deleteMarkers();
        $scope.map.panTo(new google.maps.LatLng($scope.eventInfo.Latitude, $scope.eventInfo.Longitude));
        addEventMarker($scope.eventInfo, $scope.map);
        $scope.mapLoaded = true;
        if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
          $scope.$apply();
        }
      }
      if (typeof (getWidgetHeight) === 'function')
        getWidgetHeight('loadEventmap');
    }

    $scope.loadMap = function (w) {
      var hT = $('#mapView').offset().top,
        hH = $('#mapView').outerHeight(),
        wH = $(w).height(),
        wS = $(w).scrollTop();
      if (wS > (hT + hH - wH) && (hT > wS) && (wS + wH > hT + hH) && !$scope.mapLoaded) {
        $scope.loadEventmap();
      }
    }

    $(window).scroll(function () {
      $scope.loadMap(window);
    });

    $(".widgetBody").scroll(function () {
      $scope.loadMap(this)
    });

    $scope.$on('ShowMessage',
      function (event, val) {
        $scope.showInfoMessage(true, val);
      });

    $scope.selectVenue = function (venue) {
      $scope.selectedVenue = venue;
      $scope.selectedVenueName = venue.VenueName;
      $scope.eventInfo.Latitude = venue.Latitude;
      $scope.eventInfo.Longitude = venue.Longitude;
      deleteMarkers();
      if ($scope.selectedVenue.Latitude) {
        $scope.map.panTo(new google.maps.LatLng($scope.eventInfo.Latitude, $scope.eventInfo.Longitude));
        addEventMarker($scope.eventInfo, $scope.map);
      }
      $scope.filterTickets();
    }

    $scope.selectDate = function (date) {
      $scope.selectedDate = date;
      $scope.filterTickets();
    }

    $scope.resetForm = function (form) {
      if (!form)
        return;
      form.$setPristine();
      form.$setUntouched();
    }

    $scope.showPasswordForm = function () {
      $scope.eventPassword = '';
      $scope.resetForm($scope.eventPasswordForm);
      $scope.popVEPassword = true;
      $scope.showLoader = false;
    }

    $scope.showMembersForm = function () {
      $scope.popVEMembers = true;
      $scope.showLoader = false;
    }

    $scope.showJoinWaitListForm = function (event, ticket) {

      $mdDialog.show({
        locals: { ticket: ticket, phoneRequired: $scope.eventInfo.IsPhoneRequired },
        controller: ['$scope', 'ticket', 'phoneRequired', '$mdDialog', '$mdToast', '$filter', DialogJoinWaitListController],
        templateUrl: 'join-waitlist.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: event,
        clickOutsideToClose: true
      })
        .then(function (json) {
          if (json) {
            $scope.showLoadingMessage(true, '');
            json.EventId = $attrs.eventid;
            $http.post('/eventmanagement/AddToWaitlist', {
              json: angular.toJson(json)
            }).then(function (response) {
              $scope.showLoadingMessage(false, '');
              if (response.data) {
                $scope.showSimpleToast('success-toast', 'Added to waitlist successfully');
              }
              else {
                $scope.showSimpleToast('error-toast', 'Error occurred. Please try again.');
              }
            }, function (error) {
              $scope.showLoadingMessage(false, '');
              $scope.showSimpleToast('error-toast', 'Error occurred. Please try again.');
            });
          }
        });
    }

    $scope.showCancelReleaseTicket = function (show) {
      $scope.popCancelReleaseTicket = show;
    }

    $scope.cancelReleaseTicket = function () {
      if ($scope.waitlistId > 0) {
        $scope.showLoadingMessage(true, 'Processing...');
        $http.post('/eventmanagement/cancelwaitlist',
          { waitlistId: $scope.waitlistId, eventId: $attrs.eventid }
        ).then(function (response) {
          if (response.data) {
            $scope.showLoadingMessage(false, '');
            $scope.showSimpleToast('success-toast', 'Tickets cancelled successfully');
            setTimeout(function () { $window.location.href = $scope.eventInfo.EventUrl; }, 1000);
          }
          else {
            $scope.showSimpleToast('error-toast', 'Error occurred. Please try again.');
          }
        }, function (error) {
          $scope.showLoadingMessage(false, '');
          $scope.showSimpleToast('error-toast', 'Error occurred. Please try again.');
        });
      }
      else
        $scope.showSimpleToast('error-toast', 'Invalid waitlistId.');
    }

    $scope.initController = function (state) {
      if (state == 1)
        $scope.ShowPrivateInvateMessage();
      else if (state == 2)
        $scope.showPasswordForm();
      else if (state == 3)
        $scope.showMembersForm();
      else {
        var isAccessCodeFromUrl = true;
        eventInfoService.loadInfo($attrs.eventid, (window["requestedPromoCode"] != undefined ? requestedPromoCode : ''), $scope.waitlistId, isAccessCodeFromUrl, eventRoleId);
        $scope.eventInfoLoaded = true;
      }
    }

    $scope.getCurrentUrl = function () {
      $scope.popVEMembers = false;
      return $location.$$absUrl;
    }

    $scope.CancelLogin = function () {
      $scope.popVEMembers = false;
      broadcastService.ReloadPage('/');
    }
    $scope.Login = function () {
      $scope.popVEMembers = false;
      accountService.StartLogin(null);
    }

    $scope.Logout = function () {
      accountService.StartLogout(null);
    }

    $scope.CancelPassword = function () {
      $scope.popVEPassword = false;
      broadcastService.ReloadPage('/');
    }

    $scope.eventPasswordProcessing = function (form) {
      if ($scope[form].$valid) {
        $scope.popVEPassword = false;
        $scope.showLoadingMessage(true, 'Checking...');
        $http.post('/eventmanagement/CheckPrivateEventAccess', {
          json: angular.toJson({
            EventId: $attrs.eventid,
            Password: $scope.eventPassword,
            IniteId: ''
          })
        }).then(function (response) {
          $scope.showLoadingMessage(false, '');
          if (response.data.Success)
            broadcastService.ReloadPage();
          else {
            $scope.incorrectPassword = true;
            $scope.privateLoginError = response.data.ErrorMessage;
            $scope.popVEPassword = true;
          }
        }, function (error) {
          $scope.showLoadingMessage(false, '');
          $scope.showPasswordForm();
        });
      }
      else {
        if ($scope[form].eventPassword.$error.required) { $scope.eventPasswordRequired = true; }
      }
    };

    $scope.CommonCloseInfoMessage = function () {
      if (isToRelod == true)
        $window.location.href = $scope.eventInfo.EventUrl;
      $scope.popInfoMessage = false;
    }

    $scope.CloseInfoMessage = $scope.CommonCloseInfoMessage;

    $scope.PrivateIniteCloseMessage = function () {
      $scope.popInfoMessage = false;
      broadcastService.ReloadPage('/');
    }

    $scope.ShowPrivateInvateMessage = function () {
      $scope.InfoMessage = "You need an invitation to view this private event. If you already have an invitation, please use that invitation link."
      $scope.CloseInfoMessage = $scope.PrivateIniteCloseMessage;
      $scope.popInfoMessage = true;
      $scope.showLoader = false;
    }

    $scope.$on('LoggedIn', function (event, param) {
      if (param === 'VEFav' + $scope.eventInfo.EventId) {
        eventInfoService.addFavorite();
        broadcastService.ReloadPage();
      }
      else if (param === 'VEVote' + $scope.eventInfo.EventId) {
        eventInfoService.voteEvent();
        broadcastService.ReloadPage();
      }
    });

    $scope.onPriceChange = function (ticket) {
      if (ticket) {
        ticket.Amount = parseFloat(ticket.PriceText.replace(/[^0-9\.]/g, ''));
        ticket.Amount = isNaN(ticket.Amount) ? 0 : ticket.Amount;
      }
      eventInfoService.recalcTotal();
      $scope.showCheckoutButton();
    }

    $scope.onPriceBlur = function (ticket) {
      ticket.Amount = (ticket.Amount < 0) || isNaN(ticket.Amount) || !ticket.Amount ? 0 : ticket.Amount;
      ticket.PriceText = getPriceText(ticket.Amount);
      $scope.onPriceChange(ticket);
    }

    $scope.onPriceFocus = function (ticket) {
      ticket.PriceText = ticket.PriceText.replace($scope.eventInfo.Currency.SymbolAsString, '');
    }

    $scope.OrderCheckout = function (webreferralId, viewOnMap) {
      var result = eventInfoService.postTickets($scope.cartDeals, webreferralId, viewOnMap, $scope.waitlistId);
      if (result == 'error') {
        $scope.showSimpleToast('error-toast', 'Please select tickets first :)');
      }
    }

    $scope.showSimpleToast = function (theme, message) {
      $mdToast.show(
        $mdToast.simple()
          .textContent(message)
          .position('bottom right')
          .hideDelay(3000)
          .theme(theme)
      );
    };

    $scope.showSimpleToast = function (theme, message) {
      $mdToast.show(
        $mdToast.simple()
          .textContent(message)
          .position('bottom right')
          .hideDelay(3000)
          .theme(theme)
      );
    };

    $scope.ClosePreview = function () {
      $window.close();
    }

    $scope.StartLogin = function (loginInfo) {
      broadcastService.CallLogin(loginInfo);
    }

    $scope.AddToFavorite = function () {
      if (!accountService.UserRegistered()) {
        accountService.StartLogin('VEFav' + $scope.eventInfo.EventId);
      }
      if ((!$scope.eventInfo) || ($scope.eventInfo.UserFavorite == true))
        return;
      eventInfoService.addFavorite();
    }

    $scope.VoteEvent = function () {
      if (!accountService.UserRegistered()) {
        accountService.StartLogin('VEVote' + $scope.eventInfo.EventId);
      }
      if ((!$scope.eventInfo) || ($scope.eventInfo.UserVote == true))
        return;
      eventInfoService.voteEvent();
    }

    $scope.showLoadingMessage = function (show, message) {
      $scope.popLoading = show;
      $scope.LoadingMessage = message;
    }

    $scope.showInfoMessage = function (show, message) {
      $scope.CloseInfoMessage = $scope.CommonCloseInfoMessage;
      $scope.InfoMessage = message;
      $scope.popInfoMessage = show;
    }

    if ($attrs.errormessage) {
      $scope.showInfoMessage(true, $attrs.errormessage);
    }

    $scope.contactOrganizer = function (event, eventName, organizerName) {
      $mdDialog.show({
        controller: ['$scope', '$mdDialog', '$mdConstant', '$mdToast', '$timeout', 'vcRecaptchaService', 'footerService', 'eventId', 'organizerId', 'eventName',
          'organizerName', DialogContactOrganizerController],
        templateUrl: 'organizer.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: event,
        scope: $scope,
        preserveScope: true,
        clickOutsideToClose: true,
        locals: {
          eventId: $scope.eventInfo.EventId,
          organizerId: $scope.eventInfo.organizerId,
          eventName: eventName,
          organizerName: organizerName
        }
      });
    };

    $scope.SetScheduleFromUnix = function (schedule) {
      let options = { year: 'numeric', month: 'long', day: 'numeric' };
      let sDate = moment.unix(schedule.StartDateUnix + new Date(schedule.StartDateUnix * 1000).getTimezoneOffset() * 60).toDate();
      schedule.ScheduleStartDate = new Date(sDate.getFullYear(), sDate.getMonth(), sDate.getDate());
      schedule.ScheduleStartTime = sDate;
      let eDate = $scope.eventInfo.DateInfo.EndDateTime;
      if (schedule.EndDateUnix) {
        eDate = moment.unix(schedule.EndDateUnix + new Date(schedule.EndDateUnix * 1000).getTimezoneOffset() * 60).toDate();
      }
      schedule.ScheduleEndDate = eDate ? new Date(eDate.getFullYear(), eDate.getMonth(), eDate.getDate()) : eDate;
      schedule.ScheduleEndTime = eDate;
      schedule.StartTimeString = formatAMPM(sDate);
      schedule.EndTimeString = formatAMPM(eDate);
      schedule.ScheduleStartDateText = schedule.ScheduleStartDate.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
    }
    function formatAMPM(date) {
      var hours = date.getHours();
      var minutes = date.getMinutes();
      var ampm = hours >= 12 ? 'p' : 'a';
      hours = hours % 12;
      hours = hours ? hours : 12; // the hour '0' should be '12'
      minutes = minutes < 10 ? '0' + minutes : minutes;
      var strTime = hours + ':' + minutes + '' + ampm;
      return strTime;
    }
    $scope.viewTicketSessionDetails = function (event, ticket, ScheduleName, IsFireworkEnable, OnlineEvent) {
      if (ticket.ScheduleList.length > 0) {
        ticket.ScheduleList.forEach(function (schedule) {
          $scope.SetScheduleFromUnix(schedule);
        });
      }
      $mdDialog.show({
        controller: ['$scope', '$mdDialog', 'ticket', 'ScheduleName', 'IsFireworkEnable', 'OnlineEvent', '$sce', DialogTicketSessionDetailsController],
        templateUrl: 'schedule.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: event,
        scope: $scope,
        preserveScope: true,
        focusOnOpen: false,
        clickOutsideToClose: true,
        locals: {
          ticket: ticket,
          ScheduleName: ScheduleName,
          IsFireworkEnable: IsFireworkEnable,
          OnlineEvent: OnlineEvent
        }
      });
    };
    $scope.viewSessionDetails = function (event, schedule, ScheduleName, IsFireworkEnable, OnlineEvent) {
      $scope.SetScheduleFromUnix(schedule);
      $mdDialog.show({
        controller: ['$scope', '$mdDialog', 'schedule', 'ScheduleName', 'IsFireworkEnable', 'OnlineEvent', '$sce', DialogSessionDetailsController],
        templateUrl: 'scheduleDetail.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: event,
        scope: $scope,
        preserveScope: true,
        focusOnOpen: false,
        clickOutsideToClose: true,
        locals: {
          schedule: schedule,
          ScheduleName: ScheduleName,
          IsFireworkEnable: IsFireworkEnable,
          OnlineEvent: OnlineEvent
        }
      });
    };

    $scope.forwardFriend = function (event, mTitle, mType) {
      $mdDialog.show({
        controller: ['$scope', '$mdDialog', '$mdConstant', '$mdToast', '$timeout', 'vcRecaptchaService', 'footerService', 'id', 'title', 'type', DialogForwardFriendController],
        templateUrl: 'forwardfriend.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: event,
        scope: $scope,
        preserveScope: true,
        clickOutsideToClose: true,
        locals: {
          id: $scope.eventInfo.EventId,
          title: mTitle,
          type: mType
        }
      });
    };

    $scope.SendMessageTo = function (mtype) {
      $scope.VEMessage.Email = '';
      $scope.VEMessage.Name = '';
      $scope.VEMessage.Message = '';
      if (mtype == 1) {
        $scope.VEShareWithFriendsForm.$setPristine();
        $scope.VEShareWithFriendsForm.$setUntouched();
        $scope.popVEShareWithFriends = true;
      } else {
        $scope.VEOrganizerMessageForm.$setPristine();
        $scope.VEOrganizerMessageForm.$setUntouched();
        $scope.popVEOrganizerMessage = true;;
      }
    }

    $scope.TrySendMessage = function (form, url) {
      if (form.$valid) {
        $scope.VEMessage.EventId = $scope.eventInfo.EventId;
        var data = {
          json: angular.toJson($scope.VEMessage)
        };

        $scope.showLoadingMessage(true, 'Sending message');

        $http.post(url, data).then(function (response) {
          $scope.showLoadingMessage(false, '');
          if (response.data && response.data.Success)
            $scope.showInfoMessage(true, "Message send succesfully");
          else
            $scope.showInfoMessage(true, response.data.ErrorMessage);
        }, function (error) {
          $scope.showLoadingMessage(false, '');
          $scope.showInfoMessage(true, "Error while sending message. Try again later.");
        });
      } else {
        $scope.submitted = true;
      }
    }

    $scope.TrySendShareWithFriendsMessage = function (form) {
      $scope.popVEShareWithFriends = false;
      $scope.TrySendMessage(form, '/notificationAPI/shareFriends');
    }

    $scope.TrySendOrganizerMessage = function (form) {
      $scope.popVEOrganizerMessage = false;
      $scope.TrySendMessage(form, '/notificationAPI/sendOrganizer');
    }

    $scope.accessCodeSuccess = false;
    $scope.enterAccessCode = function (event) {
      $mdDialog.show({
        controller: ['$http', '$scope', '$mdDialog', '$mdToast', 'eventInfoService', DialogEnterAccessCodeController],
        templateUrl: 'enter-promocode.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: event,
        clickOutsideToClose: true
      })
        .then(function (sucess) {
          if (sucess) {
            $scope.accessCodeSuccess = true;
          }
        });
    };

    $scope.removeAccessPromoCode = function (eId) {
      eventInfoService.loadInfo(eId, "", null, null, eventRoleId);
      $scope.accessCodeSuccess = false;
      if (typeof (getWidgetHeight) === 'function')
        getWidgetHeight('removeAccessPromoCode');
    };

    $scope.Dealbox = { Show: true, Text: 'Hide' }
    $scope.toggleDealbox = function (box) {
      box.Show = !box.Show;
      box.Text = box.Show ? "Hide" : "Show";
    }

    $scope.cartDeals = [];
    $scope.addDealToCart = function (deal) {
      if ($scope.eventInfo.Deals) {
        var idx = $scope.eventInfo.Deals.indexOf(deal);
        if (idx >= 0)
          $scope.eventInfo.Deals.splice(idx, 1);
      }
      if ($scope.cartDeals) {
        var idx = $scope.cartDeals.indexOf(deal);
        if (idx < 0)
          $scope.cartDeals.push(deal);
      }
      deal.Checked = true;
    }

    $scope.removeDealFromCart = function (deal) {
      if ($scope.cartDeals) {
        var idx = $scope.cartDeals.indexOf(deal);
        if (idx >= 0)
          $scope.cartDeals.splice(idx, 1);
      }
      if ($scope.eventInfo.Deals) {
        var idx = $scope.eventInfo.Deals.indexOf(deal);
        if (idx < 0)
          $scope.eventInfo.Deals.push(deal);
      }
      deal.Checked = false;
    }

    $scope.helpExclusiveDeals = function (event) {
      $mdDialog.show({
        controller: ['$scope', '$mdDialog', DialogHelpExclusiveDealsController],
        templateUrl: 'exclusive-deals-tooltip.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: event,
        clickOutsideToClose: true
      });
    };

    $scope.setSessionFBUserId = function (id) {
      $http.post('/Account/SetSessionFBUserId', {
        userId: id
      }).then(function (response) {
      }, function (error) {
        console.log(error);
      })
    };

    $scope.fbNotYet = function (event) {
      $mdDialog.show({
        controller: ['$scope', '$mdDialog', '$mdToast', '$http', DialogFBNotYetController],
        templateUrl: 'fb-not-yet.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: event,
        scope: $scope,
        preserveScope: true,
        clickOutsideToClose: true
      });
    };

    $scope.whoIsGoing = function (facebookFriends) {
      var friends = [];
      angular.forEach(facebookFriends, function (obj) {
        var friend = {
          FacebookUserId: obj.id,
          Name: obj.name,
          ProfilePictureUrl: obj.picture.data.url,
          ProfileUrl: obj.link
        }
        friends.push(friend);
      });
      var model = {
        json: angular.toJson({
          EventId: $attrs.eventid,
          facebookUser: $scope.FacebookConnect.FacebookUser,
          FacebookFriends: friends
        })
      }
      $http({
        method: "get",
        datatype: "data.json",
        url: "/EventManagement/WhoIsGoing",
        params: model
      }).then(function (response) {
        $scope.FacebookConnect = response.data;
        $scope.FacebookConnect.Connected = true;
      }, function (error) {
        console.log(error);
      })
    };

    $scope.sendPermission = function () {
      return $http({
        method: "post",
        datatype: "data.json",
        url: "/EventManagement/SaveWhoIsGoingPreference",
        data: { facebookConnect: $scope.FacebookConnect }
      })
    }

    $scope.savePermission = function (value) {
      $scope.FacebookConnect.FacebookUser.ShowEventsToFriends = value;
      $scope.sendPermission().then(function (response) {
      }, function (error) {
        console.log(error);
      });
    }

    $scope.checkECPermission = function (success, error) {
      $http({
        method: "get",
        datatype: "data.json",
        url: "/EventManagement/CheckFacebookPermission",
        params: { facebookId: $scope.FacebookConnect.FacebookUser.FacebookUserId }
      }).then(function (response) {
        $scope.FacebookConnect.FacebookUser.ShowEventsToFriends = response.data;
        if (response.data) {
          if (typeof success === "function")
            success();
        }
        else
          if (typeof error === "function")
            error();
      }, function (err) {
        console.log(err);
        $scope.FacebookConnect.FacebookUser.ShowEventsToFriends = false;
        if (typeof error === "function")
          error();
      });
    }

    $scope.safeApply = function (fn) {
      var phase = this.$root.$$phase;
      if (phase == '$apply' || phase == '$digest') {
        if (fn) {
          fn();
        }
      } else {
        this.$apply(fn);
      }
    };

    $scope.showHide = function (index) {
      if ($scope.selectedValue == index) {
        $scope.selectedValue = -1;
      } else {
        $scope.selectedValue = index;
      }
    }

    $scope.showCheckoutButton = function () {
      $scope.showCheckOutButton = false;
      angular.forEach($scope.selectedTickets,
        function (ticket, index) {
          if (!ticket.SeatContains && (ticket.Quantity > 0 || ticket.Amount > 0))
            $scope.showCheckOutButton = true;
        });
      if (typeof (getWidgetHeight) === 'function')
        getWidgetHeight('showCheckoutButton');
    }

    $scope.AddToCalendar = function (event) {
      $mdDialog.show({
        controller: ['$scope', '$mdDialog', '$mdConstant', DialogAddToCalanderController],
        templateUrl: 'addtocalander.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: event,
        clickOutsideToClose: true
      });
    };
    $scope.galleryData = [];
    $scope.currentImageIndex = 0;
    $scope.lightBox = document.createElement('div');
    $scope.openLightbox = function (images, type, item) {
      if (type == 'venue') {
        if (item != undefined)
          $scope.galleryData = [];
          $scope.galleryData.push(item);
      }
      else {
        if (item != undefined)
          $scope.galleryData = item;
      }
      let indexG;
      if (typeof images === 'object') {
        indexG = $scope.galleryData.indexOf(images);
      } else {
        indexG = images;
      }
      const imgSrc = $scope.galleryData[indexG].ImagePath;
      $scope.currentImageIndex = indexG;
      let extension = imgSrc.split(/[#?]/)[0].split('.').pop().trim();
      $scope.lightBox.classList.add('modal');
      document.getElementById('lighboxWrapper').appendChild(this.lightBox);
      let modalVidImg;
      if (type === 'video' || extension === 'mp4') {
        modalVidImg = document.createElement('video');
        modalVidImg.setAttribute('src', imgSrc);
        modalVidImg.autoplay = true;
        modalVidImg.controls = true;
      } else {
        modalVidImg = document.createElement('img');
        modalVidImg.setAttribute('src', imgSrc);
      }
      $scope.lightBox.innerHTML = '';
      $scope.lightBox.appendChild(modalVidImg);
      $scope.lightBox.classList.add('open');
      document.getElementById('lighboxWrapper').classList.add('active');
      $scope.updateControls($scope.galleryData);
    }
    $scope.prevBtn = function () {
      $scope.currentImageIndex--;
      $scope.openLightbox($scope.currentImageIndex);
    }
    $scope.nextBtn = function () {
      $scope.currentImageIndex++;
      $scope.openLightbox($scope.currentImageIndex);
    }
    $scope.updateControls = function (images) {
      if ($scope.currentImageIndex === 0) {
        document.getElementById('prev-btn').classList.add('disabled');
      } else {
        document.getElementById('prev-btn').classList.remove('disabled');
      }
      if ($scope.currentImageIndex === images.length - 1) {
        document.getElementById('next-btn').classList.add('disabled');
      } else {
        document.getElementById('next-btn').classList.remove('disabled');
      }
    }
    $scope.closeLightbox = function (event) {
      $scope.lightBox.classList.remove('open');
      document.getElementById('lighboxWrapper').classList.remove('active');
    }

    $scope.getEventRoles = function () {
      eventInfoService.getEventRoleList($attrs.eventid).then(function (res) {
        if (res.data) {
          $scope.eventRoles = res.data;
        }
      })
    }
    $scope.getEventRoles();
  }]);

isSameOrigin = function () {
  var sameOrigin;
  try {
    sameOrigin = window.parent.location.host === window.location.host;
  }
  catch (e) {
    sameOrigin = false;
  }
  return sameOrigin;
};

eventComboApp.directive("deal", function () {
  return {
    scope: {
      dealItem: "=",
      snippet: "@",
      dealSelect: "&",
      dealAction: "@"
    },
    template: '<div ng-include="snippet"></div>',
    link: function (scope, elem, attrs) {
      scope.selectDeal = function () {
        scope.dealSelect()(scope.dealItem);
      }
    },
  }
});

eventComboApp.directive('targetBlank', function () {
  return {
    compile: function (element) {
      var elems = (element.prop("tagName") === 'A') ? element : element.find('a');
      elems.attr("target", "_blank");
    }
  };
});

function DialogTicketSessionDetailsController($scope, $mdDialog, ticket, ScheduleName, IsFireworksEnable, OnlineEvent, $sce) {
  $scope.hide = function () {
    $mdDialog.hide();
  };

  $scope.cancel = function () {
    $mdDialog.cancel();
  };
  $scope.uCanTrust = function (string) {
    return $sce.trustAsHtml(string);
  }

  $scope.IsFireworksEnable = IsFireworksEnable;
  $scope.OnlineEvent = OnlineEvent;
  $scope.ScheduleName = ScheduleName;
  $scope.Ticket = ticket;
  //$scope.Ticket.ScheduleList = $scope.Ticket.ScheduleList.filter(a => a.AllowOnEvent);
  console.log($scope.Ticket);
};
function DialogSessionDetailsController($scope, $mdDialog, schedule, ScheduleName, IsFireworksEnable, OnlineEvent, $sce) {
  $scope.hide = function () {
    $mdDialog.hide();
  };
  $scope.cancel = function () {
    $mdDialog.cancel();
  };
  $scope.uCanTrust = function (string) {
    return $sce.trustAsHtml(string);
  }

  $scope.IsFireworksEnable = IsFireworksEnable;
  $scope.OnlineEvent = OnlineEvent;
  $scope.ScheduleName = ScheduleName;
  $scope.schedule = schedule;
};
function DialogEnterAccessCodeController($http, $scope, $mdDialog, $mdToast, eventInfoService) {
  $scope.hide = function () {
    $mdDialog.hide();
  };

  $scope.cancel = function () {
    $mdDialog.cancel();
  };

  $scope.accessCodeApply = function (userEnteredCode, eId) {
    $http.get('/eventmanagement/CheckAccessPromocode', { params: { eventId: eId, promoCode: userEnteredCode } }).then(function (response) {
      var result = response.data;
      if (result.Success) {
        $mdDialog.hide('sucess');
        $scope.showSimpleToast('success-toast', 'Access code applied successfully');
        eventInfoService.loadInfo(eId, userEnteredCode, null, null, eventRoleId);
        if (typeof (getWidgetHeight) === 'function')
          getWidgetHeight('accessCodeApply');
      }
      else {
        $scope.showSimpleToast('error-toast', 'Invalid code, please try again');
      }
    }, function (error) {
      $scope.showSimpleToast('error-toast', 'Unknown error!');
    });
  };

  $scope.showSimpleToast = function (theme, message) {
    $mdToast.show(
      $mdToast.simple()
        .textContent(message)
        .position('bottom right')
        .hideDelay(3000)
        .theme(theme)
    );
  };
};

function DialogHelpExclusiveDealsController($scope, $mdDialog) {
  $scope.hide = function () {
    $mdDialog.hide();
  };
  $scope.cancel = function () {
    $mdDialog.cancel();
  };
};

function DialogFBNotYetController($scope, $mdDialog, $mdToast, $http) {

  $scope.hide = function () {
    $mdDialog.hide();
  };
  $scope.cancel = function () {
    $mdDialog.cancel();
  };

  $scope.saveSettings = function () {
    $scope.sendPermission().then(function (response) {
      if (response.data) {
        $mdDialog.hide();
        $scope.showSimpleToast('success-toast', 'Social Setting successfully saved!');
        checkFBPermission(function () {
          if (!$scope.FacebookConnect.FacebookUser.ShowEventsToFriends)
            fbRevokePermission();
        }, function () {
          if ($scope.FacebookConnect.FacebookUser.ShowEventsToFriends)
            fbLogin();
        });
      } else {
        $scope.showSimpleToast('error-toast', 'Error while saving Social Setting!');
      }
    }, function (error) {
      $scope.showSimpleToast('error-toast', 'Error while saving Social Setting!');
    });
  };

  $scope.showSimpleToast = function (theme, message) {
    $mdToast.show(
      $mdToast.simple()
        .textContent(message)
        .position('bottom right')
        .hideDelay(3000)
        .theme(theme)
    );
  };
};

function DialogJoinWaitListController($scope, ticket, phoneRequired, $mdDialog, $mdToast, $filter) {
  $scope.ticket = ticket;
  $scope.phoneRequired = phoneRequired;
  $scope.Quants = $filter('filter')(ticket.Quants,
    function (value) {
      return value != 0;
    });

  $scope.hide = function () {
    $mdDialog.hide();
  };

  $scope.cancel = function () {
    $mdDialog.cancel();
  };

  $scope.eventJoinWaitListProcessing = function (form) {
    if ($scope[form].$valid) {
      var json = {
        Email: $scope.eventJoinWaitListEmail,
        Name: $scope.eventJoinWaitListName,
        Phone: $scope.eventJoinWaitListPhone,
        TicketQty: $scope.eventJoinWaitListTicketQty,
        TicketId: $scope.ticket.TQDId
      };
      $mdDialog.hide(json);
    }
    else {
      if ($scope[form].eventJoinWaitListEmail.$error.required) { $scope.eventJoinWaitListEmailRequired = true; }
    }
  };

  $scope.showSimpleToast = function (theme, message) {
    $mdToast.show(
      $mdToast.simple()
        .textContent(message)
        .position('bottom right')
        .hideDelay(3000)
        .theme(theme)
    );
  };
};

eventComboApp.controller('tickets', ["$scope", "$filter", "$attrs", function ($scope, $filter, $attrs) {
  $scope.dealBox = false;
  $scope.$watch('dealBox', function () {
    $scope.toggleText = $scope.dealBox ? 'Hide' : 'Show';
  });

  $scope.dealsArray = props;

  $scope.cartDeals = [];
  $scope.cartDealsMap = [];
  $scope.id = [];

  $scope.addToCart = function (id) {
    $scope.result = $filter('filter')($scope.dealsArray, { dealid: id })[0];
    $scope.cartDeals.push($scope.result);
  }
  $scope.removeFormCart = function (id) {
    $scope.result = $filter('filter')($scope.cartDeals, { dealid: id })[0];
    $scope.dealsArray.push($scope.result);
  }
  $scope.addToCartMap = function (id) {
    if ($scope.id.indexOf(id) != -1) {
      alert("This item is already in Cart!");
    }
    else {
      $scope.result = $filter('filter')($scope.dealsArray, { dealid: id })[0];
      $scope.cartDealsMap.push($scope.result);
      $scope.id.push($scope.result.dealid);
      $scope.$apply();
    }
  }
}]);
/****************************************************************************/
eventComboApp.service('eventInfoService', ['$http', '$rootScope', '$cookies', '$window', '$filter', 'broadcastService', '$location',
  function ($http, $rootScope, $cookies, $window, $filter, broadcastService, $location) {

    var eventInfo = {};
    var waitlistInfo = {};
    var selectedImage = 0;

    var monthlyWeekList = [
      { Name: "First", Value: 1 },
      { Name: "Second", Value: 2 },
      { Name: "Third", Value: 3 },
      { Name: "Fourth", Value: 4 },
      { Name: "Fifth", Value: 5 }
    ];

    function getEventDateTimeInfoString(dateInfo, showTimeZone) {
      var result = "";
      var timezone = "";
      if (showTimeZone && dateInfo.TimeZoneShortName)
        timezone = " " + dateInfo.TimeZoneShortName;
      if (dateInfo.Frequency.toLowerCase() === "single") {
        result = FormatDateTimeWithWeekday(dateInfo.StartDateTime) + timezone;
        if (dateInfo.EndDateTime !== dateInfo.StartDateTime)
          result = result + ' to ' + FormatDateTimeWithWeekday(dateInfo.EndDateTime) + timezone;
      }
      else if (dateInfo.Frequency.toLowerCase() === "monthly") {
        if (dateInfo.MonthlyDay)
          result = "Monthly, every " + ordinalSuffix(dateInfo.MonthlyDay) + " day of month, "
            + FormatTime(dateInfo.NextDateTime) + timezone + " to " + FormatTime(dateInfo.EndDateTime) + timezone
            + ", From " + FormatDate(dateInfo.NextDateTime) + " to " + FormatDate(dateInfo.EndDateTime);
        else
          result = "Monthly, every " + monthlyWeekList[dateInfo.MonthlyWeekNum].Name + " week of month ("
            + dateInfo.Weekdays.join(', ') + "), " + FormatTime(dateInfo.NextDateTime) + timezone + " to " + FormatTime(dateInfo.EndDateTime) + timezone
            + ", From " + FormatDate(dateInfo.NextDateTime) + " to " + FormatDate(dateInfo.EndDateTime);
      }
      else if (dateInfo.Frequency.toLowerCase() === "daily") {
        result = "Daily, " + FormatTime(dateInfo.NextDateTime) + timezone + " to " + FormatTime(dateInfo.EndDateTime) + timezone
          + ", From " + FormatDate(dateInfo.NextDateTime) + " to " + FormatDate(dateInfo.EndDateTime);
      }
      else if (dateInfo.Frequency.toLowerCase() === "custom") {
        result = dateInfo.CustomDatesString;
      }
      else {
        result = 'Weekly, (' + dateInfo.Weekdays.join(', ') + ') ' + FormatTime(dateInfo.NextDateTime) + timezone + ' to '
          + FormatTime(dateInfo.EndDateTime) + timezone + ', From ' + FormatDate(dateInfo.NextDateTime) + " to " + FormatDate(dateInfo.EndDateTime);
      }
      return result;
    }

    var loadInfo = function (eventId, accessCode, waitlistId, isAccessCodeFromUrl, eventRoleId) {
      if (!isAccessCodeFromUrl)
        isAccessCodeFromUrl = false;
      if (!waitlistId)
        waitlistId = 0;
      var oldTickets = eventInfo.Tickets;
      $http.get('/eventmanagement/geteventinfo', { params: { eventId: eventId, accessPromoCode: accessCode, waitlistId: waitlistId, isAccessCodeFromUrl: isAccessCodeFromUrl, eventRoleId: eventRoleId } }).then(function (response) {
        eventInfo = response.data;
        if (waitlistId > 0) {
          waitlistInfo = response.data.WaitlistInfo;
          console.log(response.data.WaitlistInfo.WaitListStatusId);
          isToRelod = true;
          if (response.data.WaitlistInfo.EventWaitListId == 0)
            broadcastService.ShowMessage("Invalid waitlist!");
          else if (response.data.WaitlistInfo.Expired)
            broadcastService.ShowMessage("Waitlist time expired!");
          else if (response.data.WaitlistInfo.WaitListStatusId != "InProcess")
            broadcastService.ShowMessage("Registration link expired!");
          else
            isToRelod = false;
        }
        eventInfo.DateInfo.StartDateTime = setUTC(eventInfo.DateInfo.StartDateTime);
        eventInfo.DateInfo.NextDateTime = setUTC(eventInfo.DateInfo.NextDateTime);
        eventInfo.DateInfo.EndDateTime = setUTC(eventInfo.DateInfo.EndDateTime);
        angular.forEach(eventInfo.Tickets, function (ticket, key) {
          ticket.StartDate = new Date(ticket.StartDate);
          if (ticket.TicketTypeId == 1)
            ticket.TypeName = 'FREE'
          else if (ticket.TicketTypeId == 3)
            ticket.TypeName = 'DONATE'
          else {
            ticket.TypeName = formatCurrencyAmount(ticket.Price.toFixed(2), eventInfo.Currency);
            ticket.SourcePriceText = formatCurrencyAmount(ticket.SourcePrice.toFixed(2), eventInfo.Currency);
            ticket.FeeText = formatCurrencyAmount(ticket.Fee.toFixed(2), eventInfo.Currency);
          }
          ticket.Quants = [0];
          for (i = ticket.Minimum; i <= ticket.Maximum; i++)
            ticket.Quants.push(i);
          ticket.StartDate = setUTC(ticket.StartDate);
          if (!ticket.DisplayDate)
            ticket.StartDateFormatted = "";
          else if (ticket.StartDateText)
            ticket.StartDateFormatted = ticket.StartDateText.slice(1);
          else
            ticket.StartDateFormatted = FormatDateTimeWithWeekday(ticket.StartDate);
          if (oldTickets) {
            var oldTicket = $filter('filter')(oldTickets,
              function (val, idx) {
                return val.TQDId === ticket.TQDId;
              });
            if (oldTicket.length > 0) {
              ticket.Quantity = oldTicket[0].Quantity;
              if (ticket.TicketTypeId == 3)
                ticket.Amount = oldTicket[0].Amount;
            }
          }
          if (ticket.ScheduleList.length > 0) {
            ticket.ScheduleList.forEach(function (schedule) {
              let options = { year: 'numeric', month: 'long', day: 'numeric' };
              let sDate = moment.unix(schedule.StartDateUnix + new Date(schedule.StartDateUnix * 1000).getTimezoneOffset() * 60).toDate();
              schedule.ScheduleStartDate = new Date(sDate.getFullYear(), sDate.getMonth(), sDate.getDate());
              schedule.ScheduleStartTime = sDate;
              schedule.ScheduleStartDateText = schedule.ScheduleStartDate.toLocaleDateString("en-US", { month: "short", day: "numeric" });
            });
          }
        });
        eventInfo.ScheduleList.forEach(function (schedule) {
          let options = { year: 'numeric', month: 'long', day: 'numeric' };
          let sDate = moment.unix(schedule.StartDateUnix + new Date(schedule.StartDateUnix * 1000).getTimezoneOffset() * 60).toDate();
          schedule.ScheduleStartDate = new Date(sDate.getFullYear(), sDate.getMonth(), sDate.getDate());
          schedule.ScheduleStartTime = sDate;
          schedule.ScheduleStartDateText = schedule.ScheduleStartDate.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
          console.log("dattext", schedule.ScheduleStartDateText)
        });

        var dateToday = new Date();
        dateToday.setHours(0, 0, 0, 0);
        angular.forEach(eventInfo.AvailableDates, function (d, key) {
          d.Date = new Date(d.Date);
        });
        if (eventInfo.AvailableDates.length > 1) {
          eventInfo.AvailableDates = $filter('filter')(eventInfo.AvailableDates,
            function (val, idx) {
              return val.Date.getTime() >= dateToday.getTime();
            });
        }
        eventInfo.EventDateTimeInfoString = getEventDateTimeInfoString(eventInfo.DateInfo, eventInfo.OnlineEvent);
        recalcTotal();
        broadcastService.EventInfoLoaded();
      });
    }

    var recalcTotal = function () {
      var total = 0.0;
      angular.forEach(eventInfo.Tickets, function (ticket, key) {
        if (ticket.TicketTypeId == 2 || ticket.TicketTypeId == 4)
          total = total + ticket.Quantity * ticket.Price;
        else if (ticket.TicketTypeId == 3) {
          ticket.Amount = isNaN(ticket.Amount) || ticket.Amount < 0 ? 0 : ticket.Amount;
          total = total + (isNaN(ticket.Amount) || (ticket.Amount == null ? 0 : ticket.Amount));
        }
      });
      eventInfo.TotalPrice = total;
      eventInfo.TotalPriceText = formatCurrencyAmount(total.toFixed(2), eventInfo.Currency);
    }

    var getEventInfo = function () {
      return eventInfo;
    }

    var getWaitlistInfo = function () {
      if (waitlistInfo)
        return waitlistInfo;
      else
        return {};
    }

    var setSelectedImage = function (id) {
      selectedImage = id;
    }

    var getSelectedImage = function () {
      return selectedImage;
    }

    var addFavorite = function () {
      if ((!eventInfo) || (eventInfo.UserFavorite == true))
        return;
      var model = {
        eventId: eventInfo.EventId
      }
      $http.post('/eventmanagement/AddFavorite', model).then(function (response) {
        eventInfo.FavoriteCount = response.data.Count;
        eventInfo.UserFavorite = response.data.Processed;
      });
    }

    var voteEvent = function () {
      if ((!eventInfo) || (eventInfo.UserVote == true))
        return;
      var model = {
        eventId: eventInfo.EventId
      }
      $http.post('/eventmanagement/VoteEvent', model).then(function (response) {
        eventInfo.VoteCount = response.data.Count;
        eventInfo.UserVote = response.data.Processed;
      });
    }

    var postTickets = function (dealList, webreferralId, viewOnMap, waitlistId) {
      var tickets = [];
      angular.forEach(eventInfo.Tickets, function (ticket, key) {
        var t = null;
        if ((ticket.TicketTypeId == 3) && (ticket.Amount > 0))
          t = {
            TicketQuantityDetailId: ticket.TQDId,
            Quantity: 1,
            Donate: ticket.Amount,
            Amount: ticket.Amount
          }
        else if (ticket.Quantity > 0 || (ticket.SeatContains && viewOnMap))
          t = {
            TicketQuantityDetailId: ticket.TQDId,
            Quantity: ticket.Quantity,
            Donate: 0,
            Amount: ticket.TotalPrice * ticket.Quantity
          }
        if (t != null) {
          tickets.push(t);
        }
      });
      var deals = [];
      angular.forEach(dealList, function (deal, key) {
        if (deal.Checked)
          deals.push(deal);
      });
      if (tickets.length > 0 || viewOnMap) {
        var model = {
          json: angular.toJson({
            AccessPromoCodeId: eventInfo.AccessPromoCodeId,
            AffiliateMemberId: affiliateMemberId,
            EventId: eventInfo.EventId,
            Tickets: tickets,
            Deals: deals,
            WaitlistId: waitlistId
          })
        }
        $http.post('/TicketPurchase/LockTickets', model).then(function (response) {
          var res = response.data;
          if (!res.LockId) {
            if (res.Message) {
              broadcastService.ShowMessage(res.Message)
            } else
            if (res.TicketsAvailable) {
              broadcastService.ShowMessage("Tickets temporarily locked.")
            } else {
              broadcastService.ShowMessage("Tickets unavailable.")
            }
          }
          else {
            var checkouthref = '/TicketPurchase/Checkout?lockId=' + res.LockId + '&webreferralId=' + webreferralId;
            var pickhref = '/TicketPurchase/Pick?lockId=' + res.LockId + '&webreferralId=' + webreferralId;
            if (viewOnMap) {
              $window.location.href = pickhref;
            } else {
              $window.location.href = checkouthref;
            }
          }

        });
      }
      else {
        return 'error';
      }
    }

    var getSocialPostFeed = function (socialPostEventRequest) {
      var response = $http({
        method: "get",
        datatype: "json",
        url: "/EventManagement/GetSocialPostFeed",
        params: { json: angular.toJson(socialPostEventRequest) }
      });
      return response;
    }

    var deleteSocialPostFeed = function (socialPost, eId, isEwiseFilter) {
      var response = $http({
        method: "post",
        datatype: "data.json",
        url: "/EventManagement/DeleteSocialPostFeed",
        data: { socialPostViewModel: socialPost, eventId: eId, isEventwiseFilter: isEwiseFilter }
      });
      return response;
    }

    var getEventRoleList = function (eId) {
      var response = $http({
        method: "get",
        datatype: "data.json",
        url: "/EventRoleManagement/GetEventRoleShortInfoList",
        params: { eventId: eId }
      });
      return response;
    }


    return {
      loadInfo: loadInfo,
      getEventInfo: getEventInfo,
      getWaitlistInfo: getWaitlistInfo,
      getSelectedImage: getSelectedImage,
      setSelectedImage: setSelectedImage,
      recalcTotal: recalcTotal,
      postTickets: postTickets,
      addFavorite: addFavorite,
      voteEvent: voteEvent,
      getSocialPostFeed: getSocialPostFeed,
      deleteSocialPostFeed: deleteSocialPostFeed,
      getEventRoleList: getEventRoleList
    }
  }]);
/****************************************************************************/
eventComboApp.controller('gallery', ['$scope', 'eventInfoService', '$mdDialog', '$mdMedia',
  function ($scope, eventInfoService, $mdDialog, $mdMedia) {
    $scope.images = GetImageList(eventInfoService.getEventInfo());
    $scope.$on('EventInfoLoaded', function (val) {
      $scope.images = GetImageList(eventInfoService.getEventInfo());
    });


    $scope.carouselInitializer = function () {
      setTimeout(function () {
        $scope.owl = $('#owlCarousel');
        $scope.owl.owlCarousel({
          dots: false,
          nav: false,
          responsive: {
            0: {
              items: 2
            },
            479: {
              items: 3
            },
            767: {
              items: 4
            },
            991: {
              items: 5
            },
            1170: {
              items: 6
            }
          }
        });
      }, 100);
    };

    $scope.status = '  ';
    $scope.customFullscreen = $mdMedia('xs') || $mdMedia('sm');

    $scope.showAdvanced = function (ev, id) {
      eventInfoService.setSelectedImage(id);
      var useFullScreen = ($mdMedia('sm') || $mdMedia('xs')) && $scope.customFullscreen;

      $mdDialog.show({
        controller: ['$scope', '$mdDialog', 'eventInfoService', '$filter', DialogController],
        templateUrl: 'dialog1.tmpl.html',
        parent: angular.element(document.body),
        targetEvent: ev,
        clickOutsideToClose: true,
        fullscreen: useFullScreen
      })
        .then(function (answer) {
          $scope.status = 'You said the information was "' + answer + '".';
        }, function () {
          $scope.status = 'You cancelled the dialog.';
        });

      $scope.$watch(function () {
        return $mdMedia('xs') || $mdMedia('sm');
      }, function (wantsFullScreen) {
        $scope.customFullscreen = (wantsFullScreen === true);
      });

    };

  }]);
/****************************************************************************/

eventComboApp.controller('socialFeedController', ['$scope', '$attrs', '$mdToast', 'eventInfoService', '$mdDialog', '$mdMedia',
  function ($scope, $attrs, $mdToast, eventInfoService, $mdDialog, $mdMedia) {
    $scope.LoadSocialPost = function () {
      var socialPostEventRequest =
      {
        EventId: $attrs.eventid,
        Count: $attrs.feedcount,
        SocialPostPagers: [
          {
            SocialNetwork: 'Instagram',
            MinId: '',
            NextMinId: ''
          },
          {
            SocialNetwork: 'Twitter',
            MinId: '',
            NextMinId: ''
          }
        ]
      };

      if ($scope.SocialPostFeed)
        socialPostEventRequest.SocialPostPagers = SocialPostFeed.SocialPostPagers;

      eventInfoService.getSocialPostFeed(socialPostEventRequest).then(function (response) {
        $scope.SocialPostFeed = response.data;
      }, function (error) {

      });
    };
    $scope.LoadSocialPost();
    $scope.deleteSocialPost = function (socialPostFeed, isDeleteFromThisEvent) {
      eventInfoService.deleteSocialPostFeed(socialPostFeed, $attrs.eventid, isDeleteFromThisEvent).then(function (response) {
        var result = response.data;
        if (result > 0) {
          var postDv = document.getElementById('dvSocialFeed_' + result);
          postDv.style.display = "none";
          $scope.showSimpleToast('success-toast', 'Post deleted successfully');
          $scope.LoadSocialPost();
        } else {
          $scope.showSimpleToast('error-toast', 'Error while deleting Social post!');
        }
      }, function (error) {
        $scope.showSimpleToast('error-toast', 'Error while deleting Social post!');
      });
    };
    String.prototype.parseTwitterURL = function () {
      return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+.[A-Za-z0-9-_:%&~?/.=]+/g, function (url) {
        return url.link(url);
      });
    };
    String.prototype.parseTwitterUsername = function () {
      return this.replace(/[@]+[A-Za-z0-9-_]+/g, function (u) {
        var username = u.replace("@", "")
        return u.link("https://twitter.com/" + username);
      });
    };
    String.prototype.parseTwitterHashtag = function () {
      return this.replace(/[#]+[A-Za-z0-9-_]+/g, function (t) {
        var tag = t.replace("#", "")
        return t.link("https://twitter.com/hashtag/" + tag);
      });
    };
    String.prototype.parseInstaHashtag = function () {
      return this.replace(/[#]+[A-Za-z0-9-_]+/g, function (t) {
        var tag = t.replace("#", "")
        return t.link("https://www.instagram.com/explore/tags/" + tag);
      });
    };
    $scope.showSimpleToast = function (theme, message) {
      $mdToast.show(
        $mdToast.simple()
          .textContent(message)
          .position('bottom right')
          .hideDelay(3000)
          .theme(theme)
      );
    };
  }]);

function GetImageList(eventInfo) {
  var images = [];
  if (!eventInfo || !eventInfo.ImagesUrl || !Array.isArray(eventInfo.ImagesUrl))
    return images;
  for (var i = 0; i < eventInfo.ImagesUrl.length; i++) {
    var image = { id: i + 1, thumb: eventInfo.ImagesUrl[i], img: eventInfo.ImagesUrl[i], title: eventInfo.EventTitle }
    images.push(image);
  };
  return images;
}

function DialogController($scope, $mdDialog, eventInfoService, $filter) {
  $scope.images = GetImageList(eventInfoService.getEventInfo());
  $scope.image = $filter('filter')($scope.images,
    {
      id: eventInfoService.getSelectedImage()
    })[0];
  $scope.hide = function () {
    $mdDialog.hide();
  };

  $scope.cancel = function () {
    $mdDialog.cancel();
  };

  $scope.answer = function (answer) {
    $mdDialog.hide(answer);
  };

  $scope.onkeydown = function (evt) {
    evt = evt || window.event;
    switch (evt.keyCode) {
      case 38:
        $scope.activeElement.previousElementSibling.focus();
        break;
      case 40:
        $scope.activeElement.nextElementSibling.focus();
        break;
    }
  };
}

function DialogAddToCalanderController($scope, $mdDialog, $mdConstant) {
  $scope.cancel = function () {
    $mdDialog.cancel();
  };
}

eventComboApp.directive('decimalOnly', function () {
  return {
    require: 'ngModel',
    link: function (scope, element, attr, ngModelCtrl) {
      function fromUser(number) {
        if (number) {
          var transformedInput = number.replace(/[^0-9\.]/g, '');
          var nth = 0;
          transformedInput = transformedInput.replace(/\./g, function (match, i, original) {
            nth++;
            return (nth > 1) ? "" : match;
          });
          if (transformedInput !== number) {
            ngModelCtrl.$setViewValue(transformedInput);
            ngModelCtrl.$render();
          }
          return transformedInput;
        }
        return number;
      }
      ngModelCtrl.$parsers.push(fromUser);
    }
  };
});

/****************************************************************************/

function FormatDate(date) {
  var myDate = new Date(date);
  myDate = new Date(myDate.getTime() + myDate.getTimezoneOffset() * 60000);
  var options = { year: 'numeric', month: 'numeric', day: 'numeric' };
  return myDate.toLocaleDateString('en-US', options);
}

function FormatDateTime(date) {
  var myDate = new Date(date);
  myDate = new Date(myDate.getTime() + myDate.getTimezoneOffset() * 60000);
  var options = { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric' };
  return myDate.toLocaleDateString('en-US', options);
}

function FormatDateTimeWithWeekday(date) {
  var myDate = new Date(date);
  if (Object.prototype.toString.call(date) !== '[object Date]')
    myDate = new Date(myDate.getTime() + myDate.getTimezoneOffset() * 60000);
  var options = { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric' };
  return myDate.toLocaleDateString('en-US', options);
}

function FormatTime(date) {
  var myDate = new Date(date);
  myDate = new Date(myDate.getTime() + myDate.getTimezoneOffset() * 60000);
  var options = { hour: 'numeric', minute: 'numeric' };
  return myDate.toLocaleTimeString('en-US', options);
}

function setUTC(date) {
  if (date.length == 19)
    return date + "Z";
  return date;
}

function ordinalSuffix(i) {
  var j = i % 10,
    k = i % 100;
  if (j == 1 && k != 11) {
    return i + "st";
  }
  if (j == 2 && k != 12) {
    return i + "nd";
  }
  if (j == 3 && k != 13) {
    return i + "rd";
  }
  return i + "th";
}

function formatCurrencyAmount(amount, currency) {
  var amountText = isNaN(amount) ? amount : Number(amount).toFixed(2);
  if (currency && currency.Layout) {
    return currency.Layout.replace("%SN", currency.ShortName).replace("%A", amountText).replace("%S", currency.SymbolAsString);
  }
  if (currency && currency.Symbol)
    return currency.SymbolAsString + amountText;
  return amountText;
}
;

function FacebookShare(myhref) {
  FB.ui({
    method: 'share',
    href: myhref
  }, function (response) { });
  return false;
}

function FacebookSend(myhref) {
  FB.ui({
    method: 'send',
    link: myhref
  }, function (response) { });
  return false;
}

function TwitterShare(title, href) {
  window.open('https://twitter.com/intent/tweet?url=' + encodeURIComponent(href) + '&via=Eventcombo&related=Eventcombo&text=' + encodeURIComponent(title) + '', 'targetWindow', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=626,height=436');
  return false;
}

function LinkedInShare(title, href, summary) {
  window.open('https://www.linkedin.com/shareArticle?mini=true&url=' + encodeURIComponent(href) + '&title=' + encodeURIComponent(title) + '&summary=' + encodeURIComponent(summary) + '&source=Eventcombo', 'targetWindow', 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=626,height=436');
  return false;
}
;
