//add modal functionality to the jquery object
$.fn.confirm = function(message) {
  var click_handler = function() {
                        var self = this;
                        var $self = $(self);
                        $.prompt(message, {
                                  buttons: {Yes: true, No: false},
                                  opacity: 0.7,
                                  //fix for default background color of white in ie6 for iframe contents
                                  loaded: function() {
                                    $('#jqifade').attr('src', '/blank.html');
                                  },
                                  callback: function(button_value) {
                                              if (button_value) {
                                                $self.unbind('click', click_handler);

                                                self.onclick = $.data(self, 'confirm.oldonclick');
                                                $.removeData(self, 'confirm.oldonclick');

                                                var oldclickhandlers = $.data(self, 'confirm.oldclickhandlers');
                                                for (var i in oldclickhandlers)
                                                  $self.click(oldclickhandlers[i]);
                                                $.removeData(self, 'confirm.oldclickhandlers');

                                                $self.click();

                                                //NOTE: jquery doesn't trigger native clicks on links for IE because
                                                //      IE will follow the link; however, it results in the native .onclick
                                                //      handler also not firing (a bug?). So we manually trigger the event here.
                                                //      see jQuery.trigger();
                                                var fn = $.isFunction( self['click'] || null )
                                                if (fn && ($.nodeName(self, 'a'))) {
                                                  self['onclick']();
                                                }
                                              }
                                            }
                        });

                        return false;
                      };

  return this .each(function() {
                      //note: ie doesn't appear to have an onclick at this point, but will fail with a null onclick
                      this.onclick = this.onclick || function() {};
                      //store the onclick before removing it
                      $.data(this, 'confirm.oldonclick', this.onclick);

                      this.onclick = null;

                      var events = $.data(this, 'events');

                      if (!events) return;

                      //store the old click event handlers before removing them
                      var oldclickhandlers = [];
                      for (var i in events['click']) {
                        oldclickhandlers.push(events['click'][i]);
                      };
                      $.data(this, 'confirm.oldclickhandlers', oldclickhandlers);
                    })
              .unbind('click')
              .click(click_handler);
};


//declaration closure
(function($) {
  //mark the body for help with other overlays when in modal mode
  $.aop.before({target: $, method: 'jqmShow'}, function() {
    $('body').addClass('in_modal');
  });

  $.aop.before({target: $, method: 'jqmHide'}, function() {
    $('body').removeClass('in_modal');
  });

  $.fn.modal_link = function(options) {
    new ModalController(options).modal_link(this);
    return this;
  };

  $.fn.modal_form = function(options) {
    new ModalController(options).modal_form(this);
    return this;
  };

})(jQuery);


function ModalController(options) {
  this.options = $.extend({}, ModalController.defaults, options);
};


//statics
ModalController.defaults = {
  livequery: false,
  beforeOpen: null,
  success: null,
  complete: null
}

ModalController.modal_defaults = {
  modal: true,
  overlay: 70,
  trigger: false,
  closeClass: false,
  onShow: function(hash) {
    if ($('#cluetip-close')[0])
      $('#cluetip-close').click();
    hash.w.show();
  },
  onHide: function(hash) {
    hash.o.remove();
    $('#jmodal_contents').html('');
    hash.w.hide();
    ModalController.notify_close();
  }
}

ModalController.set_current = function(controller) {
  if (controller && this.get_current())
    this.suspend();

  $.data($('#jmodal_window')[0], 'modalFlowController', controller);
}

ModalController.clear_current = function() {
  $.removeData($('#jmodal_window')[0], 'modalFlowController');

  if (this.get_suspended())
    this.resume();
}

ModalController.get_current = function() {
  return $.data($('#jmodal_window')[0], 'modalFlowController');
}

ModalController.set_suspended = function(suspended) {
  $.data($('#jmodal_window')[0], 'suspendedModalFlowController', suspended);
}

ModalController.clear_suspended = function() {
  $.removeData($('#jmodal_window')[0], 'suspendedModalFlowController');
}

ModalController.get_suspended = function() {
  return $.data($('#jmodal_window')[0], 'suspendedModalFlowController');
}

ModalController.notify_close = function()  {
  var controller = ModalController.get_current();
  if (controller) {
    controller.notify_close();
  }
}

ModalController.notify_success = function(data) {
  var controller = ModalController.get_current();
  if (controller) {
    controller.notify_success(data);
  }
}

ModalController.system_error = function(data) {
  //stop any current controllers - they're probably busted anyways
  if (ModalController.get_current())
    $('#jmodal_window').jqmHide();
  if (data != '') {
    var controller = new ModalController();
    controller.start();
    controller.show_in_modal("<div id='error_container' style='overflow:auto; width:615px; height:400px;'>" + data +"</div>");

    //add click handler for the overlay to close the modal
    $('div.jqmOverlay').click(function() {$('#jmodal_window').jqmHide();});
  }
}

ModalController.suspend = function() {
  var currentController = this.get_current();

  this.set_suspended(currentController);

  if (!$('#suspended_modal_contents')[0]) {
    $('#jmodal_window').after('<div id="suspended_modal_contents" style="display:none;">&nbsp;</div>');
  }

  $('#suspended_modal_contents').empty();
  currentController.get_modal_contents().contents().appendTo('#suspended_modal_contents');
}

ModalController.resume = function() {
  var suspended = this.get_suspended();
  this.clear_suspended();

  $('#jmodal_contents').empty();
  $('#suspended_modal_contents').contents().appendTo('#jmodal_contents');

  this.set_current(suspended);

  suspended.get_modal().jqmShow();
}


//public methods
ModalController.prototype = {
  started: false,
  success: false,
  success_data: null,

  start: function() {
    this.started = true;
    this.prepare_modal();
    ModalController.set_current(this);

    if (this.options.beforeOpen)
      this.options.beforeOpen();

    this.get_modal().jqmShow();
  },

  prepare_to_show: function() {
    if (!this.started) {
      this.start();
    }

    this.get_modal_contents().spinner();
  },

  modal_link: function(selector) {
    var controller = this;
    if (this.options.livequery) {
      $(selector).livequery(function() { controller.modalize_element_url(this); });
    } else {
      $(selector).each(function() { controller.modalize_element_url(this); });
    }

    $(selector)
      .ajaxLink(null, {
        livequery: this.options.livequery,
        beforeSend: this.prepare_to_show.bind(this),
        success: this.show_in_modal.bind(this)
    });
  },

  modal_form: function(selector) {
    var controller = this;

    $(selector)
      .each(function() { controller.modalize_element_url(this); })
      .ajaxForm({
            beforeSubmit: this.prepare_to_show.bind(this),
            success:      this.show_in_modal.bind(this)});
  },

  modal_ajax: function(options) {
    options =
    $.extend({}, options, {
        url: this.modalize_url(options.url),
        beforeSend: this.prepare_to_show.bind(this),
        success: this.show_in_modal.bind(this)
    });

    $.ajax(options);
  },

  modalize_element_url: function(domElement) {
    var $el = $(domElement);
    var attr = ($el).is('a') ? 'href' : 'action';

    $el.attr(attr, this.modalize_url($el.attr(attr)));
  },

  modalize_url: function(url) {
    if (url.indexOf('modal=true') >= 0)
      return url;

    var join_char = (url.indexOf('?') >= 0) ? '&' : '?';
    return url + join_char + 'modal=true';
  },

  get_modal: function() {
    return $('#jmodal_window');
  },

  get_modal_contents: function() {
    return $('#jmodal_contents');
  },

  show_in_modal: function(data) {
    this.get_modal_contents().html(data);
    this.instrument_modal_contents();

    //close in response to some dom (rather than executed js); so that this controller finishes it's
    //work before closing (prevents timing problems from suspend/resume operations)
    if (this.get_modal_contents().find('div#success_results .close').is(':contains("true")'))
      this.get_modal().jqmHide();
  },

  instrument_modal_contents: function() {
    var $modal = this.get_modal();
    this.modal_form($modal.find('form'));

    $modal.jqmAddClose($('.close_modal, a.cancel, input.cancel', $modal));
  },

  notify_close: function() {
    if (this.success && this.options.success)
      //in IE7, you can't pass null/or undefined as the arguments array to apply
      this.options.success.apply(this.options, this.success_data || []);

    if (this.options.complete)
      this.options.complete();

    this.reset();
  },

  reset: function() {
    this.started = false;
    this.success = false;
    this.success_data = null;
    ModalController.clear_current();
  },

  notify_success: function(data) {
    // console.log(data)
    this.success = true;
    this.success_data = data;
  },

  prepare_modal: function() {
    //prepare the modal the first time, does nothing subsequently
    this.get_modal().jqm(ModalController.modal_defaults);
  }
};