/**
 * Async toggler is a link that switches between on and off state
 * 
 * When state is changed, toggler switches href as well as body and fires 
 * appropriate events
 */
jQuery.fn.selectNamedObject = function(action, p1) {
  switch(action) {
  
    // Initialize
    case 'init':
      var settings = jQuery.extend({
        'option_class' : 'object_option', 
        'add_object_url' : null, 
        'object_name' : 'object', 
        'add_object_message' : App.lang('Please insert new object name'), 
        'on_new_object' : null,
        'success_event' : null
      }, p1);
      break;
      
    // Set selected value
    case 'set_value':
      var value = p1;
      break;
      
    // Update ID name map
    case 'update_map':
      var objects = p1;
      break;
      
  } // switch
  
  // Loop through each found select and execute action on it
  return this.each(function() {
    var select = $(this);
    
    switch(action) {
    
      // Initialize
      case 'init':
        if(settings.add_object_url) {
          var last_option = select.find('option.object_option:last');
          
          if(last_option.length > 0) {
            last_option.after('<option class="new_object_option" value="">' + App.lang('New...') + '</option>');
            last_option.after('<option value=""></option>');
          } else {
            select.append('<option class="new_object_option" value="">' + App.lang('New...') + '</option>');
          } // if
          
          select.change(function() {
            var selected_option = select.find('option:selected');
            
            if(selected_option.attr('class') == 'new_object_option') {
              var object_name = jQuery.trim(prompt(settings.add_object_message, ''));
              
              if(object_name) {
                
                // Lets check if this object already exists, and if it does, select it
                var name_used = false;
                select.find('option.object_option').each(function() {
                  if($(this).text().toLowerCase() == object_name.toLowerCase()) {
                    name_used = $(this).attr('value');
                  } // if
                });
                
                if(name_used) {
                  select.selectNamedObject('set_value', name_used);
                  return;
                } // if
                
                // Object does not exist, create a new one
                select.attr('disabled', true);
                
                var post_data = { 'submitted' : 'submitted' };
                post_data[settings['object_name'] + '[name]'] = object_name;
                
                $.ajax({
                  'url' : App.extendUrl(settings.add_object_url, { 'async' : 1 }),
                  'type' : 'POST',
                  'data' : post_data,
                  'success' : function(response) {
                    select.attr('disabled', false);
                    
                    var new_object_option = $('<option></option>').addClass('object_option').attr('value', response['id']).text(object_name);
                    
                    var object_options = select.find('option.object_option');
                    if(object_options.length > 0) {
                      var object_id_name_map = {};
                      
                      var added = false;
                      object_options.each(function() {
                        var option = $(this);
                        
                        if(!added) {
                          if(object_name < option.text()) {
                            option.before(new_object_option);
                            
                            object_id_name_map[response['id']] = object_name;
                            added = true;
                          } // if
                        } // if
                        
                        object_id_name_map[option.attr('value')] = option.text();
                      });
                      
                      if(!added) {
                        select.find('option.object_option:last').after(new_object_option);
                        object_id_name_map[response['id']] = object_name;
                      } // if
                    } else {
                      select.find('option.new_object_option').before(new_object_option);
                      select.find('option.new_object_option').before('<option value=""></option>');
                      
                      var object_id_name_map = {};
                      object_id_name_map[response['id']] = object_name;
                    } // if
                    
                    select.selectNamedObject('set_value', response['id']);
                    
                    if(settings.on_new_object) {
                      
                      // Callback
                      if(typeof(settings.on_new_object) == 'function') {
                        settings.on_new_object(response['id'], object_name, object_id_name_map);
                        
                      // Name of the callback function
                      } else if(typeof(window[settings.on_new_object]) == 'function') {
                        window[settings.on_new_object](response['id'], object_name, object_id_name_map);
                      } // if
                      
                    } // if
                    
                    //on success trigger event
                    if(settings.success_event) {
                    	App.Wireframe.Events.trigger(settings.success_event, [ response, object_id_name_map, settings.additional_event_params ]);
                    } //if
                  },
                  'error' : function() {
                    select.attr('disabled', false);
                    
                    App.Wireframe.Flash.error('Failed to create a new :name based on data you provided. Please try again later', { 'name' : settings.object_name });
                  }
                });
              } else {
                select.val(selected_option); // put back old value since "New..." won't be valid option anyway
              } // if
            } // if
          });
        } // if
        
        break;
        
      // Set value
      case 'set_value':
        select.val(value).change();
        
        if(typeof($.mobile) == 'object') {
          select.selectmenu("refresh");
        } // if
        
        break;
        
      // Update options map
      case 'update_map':
        var old_options = select.find('option.object_option').addClass('old_object_option').removeClass('object_option');
        var first = true;
        
        for(var object_id in objects) {
          var new_option = $('<option></option>').addClass('object_option').attr('value', object_id).text(objects[object_id]);
          
          if(first) {
            if(old_options.length < 1) {
              select.find('option.new_object_option').before(new_option).before('<option value=""></option>');
            } else {
              select.find('option.old_object_option:last').after(new_option);
            } // if
            
            first = false;
          } else {
            select.find('option.object_option:last').after(new_option);
          } // if
        } // for
        
        // Clear old options
        old_options.remove(); 
        
        // Update for mobile interface
        select.selectmenu("refresh");
        
        break;
    } // switch
  });
};