Date.prototype.customFormat = function(formatString) {
  var YYYY,YY,MMMM,MMM,MM,M,DDDD,DDD,DD,D,hhh,hh,h,mm,m,ss,s,ampm,dMod,th;
  YY = ((YYYY = this.getFullYear()) + "").substr(2, 2);
  MM = (M = this.getMonth() + 1) < 10 ? ('0' + M) : M;
  MMM = (MMMM = ["January","February","March","April","May","June","July","August","September","October","November","December"][M - 1]).substr(0, 3);
  DD = (D = this.getDate()) < 10 ? ('0' + D) : D;
  DDD = (DDDD = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][this.getDay()]).substr(0, 3);
  th = (D >= 10 && D <= 20) ? 'th' : ((dMod = D % 10) == 1) ? 'st' : (dMod == 2) ? 'nd' : (dMod == 3) ? 'rd' : 'th';
  formatString = formatString.replace("#YYYY#", YYYY).replace("#YY#", YY).replace("#MMMM#", MMMM).replace("#MMM#", MMM).replace("#MM#", MM).replace("#M#", M).replace("#DDDD#", DDDD).replace("#DDD#", DDD).replace("#DD#", DD).replace("#D#", D).replace("#th#", th);

  h = (hhh = this.getHours());
  if (h == 0) h = 24;
  if (h > 12) h -= 12;
  hh = h < 10 ? ('0' + h) : h;
  ampm = hhh < 12 ? 'am' : 'pm';
  mm = (m = this.getMinutes()) < 10 ? ('0' + m) : m;
  ss = (s = this.getSeconds()) < 10 ? ('0' + s) : s;
  return formatString.replace("#hhh#", hhh).replace("#hh#", hh).replace("#h#", h).replace("#mm#", mm).replace("#m#", m).replace("#ss#", ss).replace("#s#", s).replace("#ampm#", ampm);
};

Date.prototype.setISO8601 = function (string) {
  var milliseconds = Date.parse(string);

  // Safari versions before 5.1 (pre Mac OS X Lion) do not support native parsing of ISO 8601 dates.
  if (isNaN(milliseconds)) {
    var regexp = "([0-9]{4})(-([0-9 ]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
    var d = string.match(new RegExp(regexp));

    var offset = 0;
    var date = new Date(d[1], 0, 1);

    if (d[3]) {
      date.setMonth(d[3] - 1);
    }
    if (d[5]) {
      date.setDate(d[5]);
    }
    if (d[7]) {
      date.setHours(d[7]);
    }
    if (d[8]) {
      date.setMinutes(d[8]);
    }
    if (d[10]) {
      date.setSeconds(d[10]);
    }
    if (d[12]) {
      date.setMilliseconds(Number("0." + d[12]) * 1000);
    }
    if (d[14]) {
      offset = (Number(d[16]) * 60) + Number(d[17]);
      offset *= ((d[15] == '-') ? 1 : -1);
    }

    offset -= date.getTimezoneOffset();
    var time = (Number(date) + (offset * 60 * 1000));
    this.setTime(Number(time));
  } else {
    var offset_milliseconds = this.getTimezoneOffset() * 60 * 1000;
    this.setTime(milliseconds - offset_milliseconds);
  }
};

function getGigs(JSONData) {
  var bcGigWidget = '';
  bcGigWidget = bcGigWidget + '<div id="bc-gig-widget" style="display:none;"><p id="bc-gig-widget-title">Upcoming Shows</p><div id="bc-gig-widget-scroller"><table id="bc-gig-widget-gigs" cellpadding="0" cellspacing="0" border="0">';
  if (JSONData != null) {
    if (JSONData.band.gigs.length > 0) {
      for (i = 0; i < JSONData.band.gigs.length; i++) {
        var bcGig = JSONData.band.gigs[i];
        bcGigWidget = bcGigWidget + '<tr class="bc-gig-widget-gig" id="bc-gig-widget-gig-' + [i] + '">';
        bcGigDate = bcGig.event_date;
        if (bcGig.event_name && bcGig.local_start_at) {
          var bcGigDate = new Date();
          bcGigDate.setISO8601(bcGig.local_start_at);

          bcGigWidget = bcGigWidget + '<td class="bc-gig-widget-gig-date" id="bc-gig-widget-gig-date-' + [i] + '">' + bcGigDate.customFormat('<span class="bc-gig-widget-gig-month">#MMM#</span><span class="bc-gig-widget-gig-day">#DDD# #D##th#</span>') + '</td>';

          bcGigWidget = bcGigWidget + '<td class="bc-gig-widget-gig-name" id="bc-gig-widget-gig-name-' + [i] + '">';
          bcGigWidget = bcGigWidget + '<span class="bc-gig-widget-event-name">' + bcGig.event_name + ' @ ' + bcGig.local_start_at_time + '</span>';
          if (typeof(bcGig.venue) != 'undefined' && bcGig.venue.name && bcGig.venue.city_name) {
            bcGigWidget = bcGigWidget + '<span class="bc-gig-widget-venue">' + bcGig.venue.name + ', ' + bcGig.venue.city_name + '</span>';
          }
          bcGigWidget = bcGigWidget + '</td>';

          bcGigWidget = bcGigWidget + '<td>';
          if (typeof(bcGig.venue) != 'undefined' && bcGig.venue.map_url) {
            bcGigWidget = bcGigWidget + '<a class="bc-gig-widget-gig-map" id="bc-gig-widget-gig-map-' + [i] + '" title="Show Map" href="' + bcGig.venue.map_url + '" target="blank">Show Map</a>';
          }
          if (bcGig.ical_url) {
            bcGigWidget = bcGigWidget + '<a class="bc-gig-widget-gig-ics" id="bc-gig-widget-gig-ics-' + [i] + '" title="Download Calendar Event" href="' + bcGig.ical_url + '" target="blank">Download Calendar Event</a>';
          }
          if (bcGig.ticket_url) {
            bcGigWidget = bcGigWidget + '<a class="bc-gig-widget-gig-ticket-url" id="bc-gig-widget-gig-ticket-url-' + [i] + '" title="Buy Tickets For This Show" href="' + bcGig.ticket_url + '" target="blank" style="color: #FFF!important;">Buy Tix</a>';
          }
          if (bcGig.facebook_event_url) {
            bcGigWidget = bcGigWidget + '<a class="bc-gig-widget-gig-facebook" id="bc-gig-widget-gig-facebook-url-' + [i] + '" title="Facebook Event Page" href="' + bcGig.facebook_event_url + '" target="blank">Facebook Event</a>';
          }
          bcGigWidget = bcGigWidget + '</td>';
        }
        bcGigWidget = bcGigWidget + '</tr>';
      }
    } else {
      bcGigWidget = bcGigWidget + '<tr><td class="bc-gig-widget-no-gigs">No upcoming shows</td></tr>';
    }
    bcGigWidget = bcGigWidget + '</table></div><p id="bc-gig-widget-title-coda">Powered by <a id="bandcentral" title="BandCentral - Artist Management Tools" href="http://www.bandcentral.com" target="_blank" style="color: #FFF!important;">BandCentral</a></p></div>';
  }

  var bcGigWidgetStyle = '';
  if (typeof bcGigWidgetWidth != 'undefined' && bcGigWidgetWidth != '') {
    bcGigWidgetStyle = bcGigWidgetStyle + '#bc-gig-widget {width:' + bcGigWidgetWidth + 'px;}';
  }
  if (typeof bcGigWidgetMaxHeight != 'undefined' && bcGigWidgetMaxHeight != '') {
    bcGigWidgetStyle = bcGigWidgetStyle + '#bc-gig-widget #bc-gig-widget-scroller {max-height:' + bcGigWidgetMaxHeight + 'px;}';
  }
  if (typeof bcGigWidgetBackgroundColor != 'undefined' && bcGigWidgetBackgroundColor != '') {
    bcGigWidgetStyle = bcGigWidgetStyle + '#bc-gig-widget {background:#' + bcGigWidgetBackgroundColor + ';}';
  }
  if (typeof bcGigWidgetTextColor != 'undefined' && bcGigWidgetTextColor != '') {
    bcGigWidgetStyle = bcGigWidgetStyle + '#bc-gig-widget, #bc-gig-widget #bc-gig-widget-gigs, #bc-gig-widget p#artist-name small {color:#' + bcGigWidgetTextColor + ';}';
  }
  if (typeof bcGigWidgetLinkColor != 'undefined' && bcGigWidgetLinkColor != '') {
    bcGigWidgetStyle = bcGigWidgetStyle + '#bc-gig-widget a, #bc-gig-widget p#artist-name, #bc-gig-widget td.bc-gig-widget-gig-name {color#:' + bcGigWidgetLinkColor + ';}';
  }
  if (typeof bcGigWidgetLineColor != 'undefined' && bcGigWidgetLineColor != '') {
    bcGigWidgetStyle = bcGigWidgetStyle + '#bc-gig-widget ul#bc-gig-widget-gigs li.bc-gig-widget-gig {border-color#:' + bcGigWidgetLineColor + ';}';
  }

  var bcDocumentHead = document.getElementsByTagName('head')[0];

  var bcStylesheetTag = document.createElement('link');
  bcStylesheetTag.setAttribute('rel', 'stylesheet');
  bcStylesheetTag.setAttribute('type', 'text/css');
  bcStylesheetTag.setAttribute('href', JSONData.band.site + 'stylesheets/gig-widget.css');
  if (typeof bcStylesheetTag != 'undefined') {
    bcDocumentHead.appendChild(bcStylesheetTag);
  }

  var bcStyleTag = document.createElement('style');
  var bcStyleRules = document.createTextNode(bcGigWidgetStyle);
  bcStyleTag.setAttribute('type', 'text/css');
  if (bcStyleTag.styleSheet) {
    bcStyleTag.styleSheet.cssText = bcStyleRules.nodeValue;
  } else {
    bcStyleTag.appendChild(bcStyleRules);
  }
  bcDocumentHead.appendChild(bcStyleTag);

  document.getElementById('bcGigsWidgetWrapper').innerHTML = bcGigWidget;

}

