var mepr_populate_states = function(obj) { (function($) {
  var country = obj.val();
  var form = obj.closest('.mepr-form');

  if(form == undefined) { return; }

  // Clean out all the options before re-populating
  form.find('.mepr-states-dropdown option').remove();

  var states_dropdown = form.find('.mepr-states-dropdown');
  var states_text = form.find('.mepr-states-text');

  // Ensure we've found a dropdown & text element
  if (states_dropdown.length <= 0 || states_text.length <= 0) { return; }

  // Grab fieldname and value
  var fieldname = states_dropdown.data('fieldname');
  var value = states_dropdown.data('value').toString();

  if(fieldname == undefined || value == undefined) { return; }

  // Grab unique suffix
  var unique_suffix = states_dropdown.data('unique-suffix');

  // Clean up trailing whitespace
  fieldname = fieldname.replace(/^\s+/,'');
  fieldname = fieldname.replace(/\s+$/,'');
  value = value.replace(/^\s+/,'');
  value = value.replace(/\s+$/,'');

  var required = !!obj.attr('required');

  // Check if country is in the list of countries without states
  var countryWithoutStates = MeprI18n.countries_without_states && MeprI18n.countries_without_states.indexOf(country) !== -1;

  // Helper function to update the asterisk in the label
  var updateStateFieldAsterisk = function(fieldElement, isRequired) {
    var label = fieldElement.siblings('.mp-form-label').find('label');
    var labelText = label.text();
    var hasAsterisk = labelText.indexOf('*') !== -1;

    if (isRequired && !hasAsterisk) {
      // Add asterisk at the end if required and not present
      label.text(labelText + '*');
    } else if (!isRequired && hasAsterisk) {
      // Remove all asterisks if not required
      label.text(labelText.replace(/\*/g, ''));
    }
  };

  if (MeprI18n.states[country] !== undefined) {
    states_dropdown.attr('name', fieldname).attr('id', 'mepr-address-state' + unique_suffix);
    states_dropdown.show();
    states_text.removeAttr('name').removeAttr('id');
    states_text.hide();
    if (required && !countryWithoutStates) {
      states_text.prop('required', false);
      states_dropdown.attr('required','');
      updateStateFieldAsterisk(states_dropdown, true);
    } else {
      // Country doesn't require states, so remove required attribute.
      states_dropdown.prop('required', false);
      states_text.prop('required', false);
      updateStateFieldAsterisk(states_dropdown, false);
    }

    states_dropdown.append('<option value="">' + MeprI18n.please_select_state + '</option>');

    for (var st in MeprI18n.states[country]) {
      var selected = (value===st ? ' selected="selected"' : '');
      states_dropdown.append('<option value="' + st + '" ' + selected + '>' + MeprI18n.states[country][st] + '</option>');
    }
  }
  else {
    states_dropdown.removeAttr('name').removeAttr('id');
    states_dropdown.hide();
    states_text.attr('name', fieldname).attr('id', 'mepr-address-state' + unique_suffix);
    states_text.show();
    if (required && !countryWithoutStates) {
      states_dropdown.prop('required', false);
      states_text.attr('required','');
      updateStateFieldAsterisk(states_text, true);
    } else {
      // Country doesn't require states, so remove required attribute.
      states_dropdown.prop('required', false);
      states_text.prop('required', false);
      updateStateFieldAsterisk(states_text, false);
    }
  }
})(jQuery)};

var mepr_set_locate_inputs = function(country, state) { (function($) {
  if(country !== '' && state !== '') {
    // If the states are created for this country
    // but the state is goofy then just blank it out
    if(MeprI18n.states[country]!==undefined &&
       MeprI18n.states[country][state]===undefined) {
      state = '';
    }
  }

  // Set the correct values for the country or state dropdowns
  if ($('.mepr-form .mepr-countries-dropdown').length > 0) {
    $.each($('.mepr-form .mepr-countries-dropdown'), function(i, obj) {
      if($(obj).val()===undefined || $(obj).val()==='') {
        $(obj).val(country);
      }

      mepr_populate_states($(obj));
    });
  }

  // Set the states up properly where appropriate
  if ($('.mepr-form .mepr-states-dropdown').length > 0) {
    $.each($('.mepr-form .mepr-states-dropdown'), function(i, obj) {

      if($(obj).data('value')===undefined || $(obj).data('value')==='') {
        var options = $(obj).find('option');

        $.each(options, function(i, option) {
          if(state===option.value) {
            $(obj).attr('data-value',state);
            $(option).attr('selected','selected');
            return false;
          }
        });
      }

    });
  }

  if ($('.mepr-form .mepr-geo-country').length > 0) {
    $.each($('.mepr-form .mepr-geo-country'), function(i, obj) {
      $(obj).val(country);
    });
  }

  $('.mepr-form .mepr-countries-dropdown').trigger('mepr-geolocated');
})(jQuery)};

var mepr_ssl_geoip_services = {
  // The services
  caseproof: {
    url:    'https://cspf-locate.herokuapp.com?callback=?',
    cindex: 'country_code',
    sindex: 'region_code',
    used:   false,
    type:   'jsonp',
  },
  //telize: { //TELIZE SHUT DOWN IN 2015
  //  url:    'https://www.telize.com/geoip',
  //  cindex: 'country_code',
  //  sindex: 'region_code',
  //  used: false,
  //  type: 'json',
  //},
  //geoplugin: {
  //  url:    'http://www.geoplugin.net/json.gp?jsoncallback=?',
  //  cindex: 'geoplugin_countryCode',
  //  sindex: 'geoplugin_regionCode',
  //  used: false,
  //  type: 'jsonp',
  //},
  //'ip-api': {
  //  url:    'http://ip-api.com/json/?callback=?',
  //  cindex: 'countryCode',
  //  sindex: 'region',
  //  used: false,
  //  type: 'jsonp',
  //},
  //freegeoip: { //Dead - needs to use https://ipstack.com/ now
  //  url:    'https://freegeoip.net/json/',
  //  cindex: 'country_code',
  //  sindex: 'region_code',
  //  used: false,
  //  type: 'json',
  //}
};

var mepr_locate = function(source_key) { (function($) {
  if(source_key==undefined) {
    source_key = 'caseproof'; // default
  }

  source = mepr_ssl_geoip_services[source_key];

  // If we've already used this source then assume we're out of choices
  if(source.used===true) {
    return mepr_set_locate_inputs('','');
  }

  $.ajax({
    url: source.url,
    method: 'GET',
    timeout: 5000, // 5 seconds ... too much? too little?
    dataType: source.type,
  })
  .done (function(data) {
    var state   = ((data[source.sindex]!==undefined) ? data[source.sindex] : '');
    var country = ((data[source.cindex]!==undefined) ? data[source.cindex] : '');

    mepr_set_locate_inputs(country, state);
  })
  .fail (function() {
    mepr_ssl_geoip_services[source_key].used=true;

    for (var k in mepr_ssl_geoip_services) {
      var next_source = mepr_ssl_geoip_services[k];

      if(next_source.used===false) {
        return mepr_locate(k);
      }
    }

    mepr_set_locate_inputs('','');
  });

  return false;
})(jQuery)};

jQuery(document).ready(function($){
  $.each($('.mepr-form .mepr-countries-dropdown'), function(i, obj) {
    mepr_populate_states($(obj));
    $(obj).on('change', function(e) {
      mepr_populate_states($(obj));
    });
  });
});
