var printf = function() { 
  var num = arguments.length; 
  var oStr = arguments[0];   
  for (var i = 1; i < num; i++) { 
    var pattern = "\\{" + (i-1) + "\\}"; 
    var re = new RegExp(pattern, "g"); 
    oStr = oStr.replace(re, arguments[i]); 
  } 
  return oStr; 
}

var SessionHandler = new Class({
    session_count_indicator: 'id_session_{0}',
    session_count: 0,
    sessions: [],
    
    initialize: function(){
        while($(printf(this.session_count_indicator, this.session_count))){
            this.session_count++;
        }
        for(var i = 0; i < this.session_count; i++){
            this.sessions[i] = i;
        }
        
        this.sessions.each(function(id){
            var element = $(printf('id_session_{0}', id));
            element.previousValue = element.getValue();
        });
        
        
        this.add_events();
    },
    
    add_events:  function(){
        this.sessions.each(function(i){
            var id = i;
            
            $(printf('id_session_{0}', id)).addEvent('change', function(event, id){
                
                var element = event.target;
                
                for (var i = 0; i < this.session_count; i++) {
                    if (i != id) {
                        var other_element = $(printf('id_session_{0}', i));
                        other_element.getElementsBySelector('option').each(function(option) {
                            if (option.value != '' && option.value == element.getValue()) {
                                option.remove();
                            }
                        });
                    }
                }
                
                element.getElementsBySelector('option').each(function(option) {
                    if (option.value != '' && option.value == element.previousValue) {
                        for (var i = 0; i < this.session_count; i++) {
                            if (i != id) {
                                var other_element = $(printf('id_session_{0}', i));
                                other_element.adopt(option.clone());
                            }
                        }
                    }
                }.bind(this));
                
                
                
                element.previousValue = element.getValue();
            }.bindWithEvent(this, id));
        }.bind(this));
    },
    
    session_options: function(){
        
    }
});

var CourseSessionHandler = new Class({
    session_count_indicator: 'id_add_session_{0}_0',
    session_count: 1,
    sessions: [],
    element_list: [],
    
    initialize: function(){
        var i = 1;
        while($(printf(this.session_count_indicator, i)) && i < 100){
            i++;
        }
        this.session_count = i;
        for(a=0; a < this.session_count; a++){
            this.sessions[a] = a;
        }
        this.add_events();
        this.element_list.each(function(elements){
            this.course_options(elements['elective_course'], elements['session'].getValue(), 'elective');
            this.course_options(elements['academic_course'], elements['session'].getValue(), 'academic');
        }.bind(this));
        
    },
    
    add_events:  function(){
        this.sessions.each(function(i){
            var id = i;
            this.element_list[id] = {
                'session':  $(printf('id_session_{0}', id)),
                'elective_course': $(printf('id_elective_course_{0}', id)),
                'academic_course': $(printf('id_academic_course_{0}', id))
            }
            
            $(printf('id_session_{0}', id)).addEvent('change', function(e){
                this.course_options($(printf('id_academic_course_{0}', id)), 
                    $(printf('id_session_{0}', id)).getValue(), 'academic');
                this.course_options($(printf('id_elective_course_{0}', id)), 
                    $(printf('id_session_{0}', id)).getValue(), 'elective');
            }.bind(this));
        }.bind(this));
    },
        
    course_options: function(course_element, session_id, course_type){
        if(session_id){
            course_element.previousValue = course_element.getValue();
            
            var lookup_vars = "?" + Object.toQueryString({session_id: session_id, course_type: course_type});
            var url ="/applications_api/course_options/" + lookup_vars;
            new Ajax(url, {method:'get', onComplete: function(response){
                course_element.empty();
                response = Json.evaluate(response);
                response.each(function(lump){
                    var vals = {'value': lump[0], 'text': lump[1]};
                    var selected = '';
                    if(lump[0] == course_element.previousValue) selected = 'selected';
                    new Element('option', {'value': lump[0], 'selected':selected}).setText(lump[1]).injectInside(course_element);
                });
            }}).request();
        }else{
            course_element.empty();
            new Element('option', {'value':''}).setText('---------').injectInside(course_element);
        }
    }
});

var WarningGrabber = new Class({
    session_count_indicator: 'id_add_session_{0}_0',
    session_count: 1,
    sessions: [],
    messages: [],
    elements_list: [],
    
    initialize: function(){
        var i = 1;
        while($(printf(this.session_count_indicator, i)) && i < 100){
            i++;
        }
        this.session_count = i;
        for(a=0; a < this.session_count; a++){
            this.sessions[a] = a;
        }
        this.add_events();
        this.elements_list.each(function(elements){
            this.get_warnings(elements);
        }.bind(this));
    
    },
    
    add_events: function(){
        this.sessions.each(function(i){
            var id = i;
            this.elements_list[id] = {
                'session': $(printf('id_session_{0}', id)),
                'academic_course': $(printf('id_academic_course_{0}', id)),
                'elective_course': $(printf('id_elective_course_{0}', id))
            }
            this.elements_list[id]['session'].addEvent('change', function(){
                this.get_warnings(this.elements_list[id]);
            }.bind(this));
            this.elements_list[id]['academic_course'].addEvent('change', function(){
                this.get_warnings(this.elements_list[id]);
            }.bind(this));
            this.elements_list[id]['elective_course'].addEvent('change', function(){
                this.get_warnings(this.elements_list[id]);
            }.bind(this));
        }.bind(this));
        
        $('edit_form').addEvent('submit', function(e){
            if(this.messages.length){
                var messages = '';
                this.messages.each(function(e, i){
                    messages = messages + e.getText() + '\n';
                });
                var answer = confirm('There are quota issues:\n\n' + messages + '\nAre you sure you wish to continue?');
                if(!answer){
                    e.stop();
                }
            }
        }.bindWithEvent(this));
    
    },
    
    get_warnings: function(elements){
        this.messages.each(function(e){ e.remove();});
        this.messages = Array();
        
        var e_course_id = elements['elective_course'].getValue();
        var a_course_id = elements['academic_course'].getValue();
        var session_id =  elements['session'].getValue();
        var nationality = $('id_nationality').getValue();
        var lookup_vars = "?" + Object.toQueryString({session_id: session_id, e_course_id: e_course_id, a_course_id:a_course_id, nationality:nationality});
        var url ="/applications_api/warnings/" + lookup_vars;
        new Ajax(url, {method:'get', onComplete: function(response){
            response = Json.evaluate(response);
            if(response['session'].length) this.display_warnings(elements['session'], response['session']);
            if(response['elective_course'].length) this.display_warnings(elements['elective_course'], response['elective_course']);
            if(response['academic_course'].length) this.display_warnings(elements['academic_course'], response['academic_course']);
        }.bind(this)}).request();
    },
    
    display_warnings: function(element, messages){
        var container = new Element('div', {'class': 'ajax_warning_message'});
        messages.each(function(e){
            var span = new Element('span', {'class': 'alert'}).setText(e);
            span.inject(container);
        });
        container.inject(element, 'before');
        this.messages[this.messages.length] = container;
    }
});

var SchoolLookup = new Class({
    parent: null,
    trigger: null, 
    response_element: null,
    response_data: null,
    
    initialize: function(trigger_id, address_id){
        this.parent = $(trigger_id);
        this.address = $(address_id);
        
        this.parent.addEvent('focus', function(){
            this.try_again();
        }.bind(this));
        
        this.trigger = new Element('a', {'href':'#', 'class':'ajax_school_lookup'});
        this.trigger.setText('Search Schools');
        this.trigger.addEvent('click', function(){
            this.search_schools();
        }.bind(this));
        
        this.trigger.inject(this.parent, 'before');
        this.response_element = new Element('select', {'class':'ajax_school_lookup', 'size':'10'});
        this.response_element.addEvent('change', function(){
            this.choose_school();
        }.bind(this));
        this.response_element.setStyle('display', 'none');
        this.response_element.injectBefore(this.parent);
    },
    
    search_schools: function(){
        this.response_element.empty();
        var lookup_vars = "?" + Object.toQueryString({'search_name': this.parent.getValue()});
       
        var url ="/applications_api/school_lookup/" + lookup_vars;
        new Ajax(url, {method:'get', onComplete: function(response){
            response = Json.evaluate(response);
            var option_data = response[0];
            this.response_data = response[1];
            option_data.each(function(od){
                var option = new Element('option', {'value': od[0], 'selected':''}).setText(od[1]);
                this.response_element.adopt(option);
            }.bind(this));
            this.response_element.setStyle('display','block');
            this.trigger.setStyle('display', 'none');
        }.bind(this)}).request();
    },
    
    try_again: function(){
        this.response_element.setStyle('display','none');
        this.trigger.setStyle('display', 'inline');
    },
    
    choose_school: function(){
        var id = this.response_element.getValue();
        if(this.response_data[id]){
            this.parent.setValue(this.response_data[id][0]);
            this.address.setValue(this.response_data[id][1]);
        }
        this.response_element.setStyle('display','none');
        this.trigger.setStyle('display', 'inline');
    }
});

var CourseSessionInformation = new Class({
    session_count_indicator: 'id_requested_session_{0}',
    session_count: 0,
    sessions: [],
    
    initialize: function(){
        while($(printf(this.session_count_indicator, this.session_count))){
            this.session_count++;
        }
        for(var i = 0; i < this.session_count; i++){
            this.sessions[i] = i;
        }
        
        this.sessions.each(function(id){
            this.add_event($(printf('id_session_{0}', id)), 'session');
            this.add_event($(printf('id_elective_course_{0}', id)), 'elective');
            this.add_event($(printf('id_academic_course_{0}', id)), 'academic');
        }.bind(this));
    },
    
    add_event: function(element, e_type){
        var info = new Element('a', {'href':'#', 'title':'Attendance Information', 'class':'ajax_info_link'}).setText('i');
        element.addEvent('change', function(){
            $$('div.ajax_info_message').each(function(e){
                if(e.el_type == e_type){
                    e.remove();
                }
            });
            info.isdisplayed = false;
        });
        info.isdisplayed = false;
        info.addEvent('click', function(){
            if(!info.isdisplayed){
                var lookup_vars = "?" + Object.toQueryString({'enquiry_id': element.getValue(), 'enquiry_type':e_type});
                var url ="/applications_api/attending_students/" + lookup_vars;
                var display_div = new Element('div', {'class': 'ajax_info_message'});
                display_div.el_type = e_type;
                new Ajax(url, {method:'get', onComplete: function(response){
                    response = Json.evaluate(response);
                    response.each(function(line, i){
                        var message = new Element('span', {'class':'alert'}).setText(line);
                        message.injectInside(display_div);
                        if(i == 2 && response.length > 3){new Element('hr').injectInside(display_div);}
                    });
                    display_div.injectBefore(element);
                    info.isdisplayed = true;
                }}).request();
            }else{
                $$('div.ajax_info_message').each(function(e){
                    if(e.el_type == e_type){
                        e.remove();
                    }
                });
                info.isdisplayed = false;
            }
        }.bind(this, info));
        info.injectBefore(element);
    }   
});

var FrontEndSession = new Class({
    initialize: function(){
        var selected = false;
        if($('id_add_session_1_1').checked){ selected=true; this.hide_selects();}
        if($('id_add_session_1_0').checked){ selected=true; this.show_selects();}
        if(!selected){
            this.hide_selects();
        }
        
        $('id_add_session_1_1').addEvent('click', function(){
            this.hide_selects();
        }.bind(this));
        $('id_add_session_1_0').addEvent('click', function(){
            this.show_selects();
        }.bind(this));
    },
        
    hide_selects: function(){
        $('field_session_1').setStyle('display', 'none');
        $('field_academic_course_1').setStyle('display', 'none');
        $('field_elective_course_1').setStyle('display', 'none');
    },
        
    show_selects: function(){
        $('field_session_1').setStyle('display', 'block');
        $('field_academic_course_1').setStyle('display', 'block');
        $('field_elective_course_1').setStyle('display', 'block');
    }
});

var FrontEndSummerAddress = new Class({
    initialize: function(){
        var selected = false;
        if($('id_guardian1_has_summer_address_1').checked){ selected=true; this.hide_fields();}
        if($('id_guardian1_has_summer_address_0').checked){ selected=true; this.show_fields();}
        if(!selected){
            this.hide_fields();
        }
        
        $('id_guardian1_has_summer_address_1').addEvent('click', function(){
            this.hide_fields();
        }.bind(this));
        $('id_guardian1_has_summer_address_0').addEvent('click', function(){
            this.show_fields();
        }.bind(this));
    },
        
    hide_fields: function(){
        $('field_guardian1_summer_address').setStyle('display', 'none');
        $('field_guardian1_summer_phone').setStyle('display', 'none');
    },
        
    show_fields: function(){
        $('field_guardian1_summer_address').setStyle('display', 'block');
        $('field_guardian1_summer_phone').setStyle('display', 'block');
    }
});

var FrontEndSummerAddress2 = new Class({
    initialize: function(){
        var selected = false;
        if($('id_guardian2_has_summer_address_1').checked){ selected=true; this.hide_fields();}
        if($('id_guardian2_has_summer_address_0').checked){ selected=true; this.show_fields();}
        if(!selected){
            this.hide_fields();
        }
        
        $('id_guardian2_has_summer_address_1').addEvent('click', function(){
            this.hide_fields();
        }.bind(this));
        $('id_guardian2_has_summer_address_0').addEvent('click', function(){
            this.show_fields();
        }.bind(this));
    },
        
    hide_fields: function(){
        $('field_guardian2_summer_address').setStyle('display', 'none');
        $('field_guardian2_summer_phone').setStyle('display', 'none');
    },
        
    show_fields: function(){
        $('field_guardian2_summer_address').setStyle('display', 'block');
        $('field_guardian2_summer_phone').setStyle('display', 'block');
    }
});

var AttachmentHandler = new Class({
    initialize: function(existing, field_id) {
        this.existing = existing;
        this.field_id = field_id;
        //this.initial_value = this.get_input().value;
        $('edit_form').addEvent('submit', this.uploader_value_check.bindWithEvent(this));
    },
    
    get_input: function() {
        // Get the hidden input whose changes we should be watching
        return $E('input.uploadResponse', $(this.field_id));
    },
    
    get_clear_button: function() {
        return $E('input.clearButton', $(this.field_id));
    },
    
    uploader_value_check: function(event) {
        var input = this.get_input();
        var response = Json.evaluate(input.value);
        var filename = response.source_filename;
        // Check whether they've already uploaded a file with this name
        for (var i=0; i<this.existing.length; i++) {
            if (this.existing[i] == filename) {
                // Show a dialog to ask whether they want to overwrite the file
                var user_response = confirm('There is already a file named '+filename+' attached to this application. '+
                            'If you continue with the upload you will overwrite this file. Are you sure '+
                            'you wish to continue?');
                if (!user_response) {
                    // Cancelled: stop the form submit and clear the upload field
                    event.stop();
                    this.get_clear_button.bind(this)().fireEvent('click', event);
                }
            }
        }
    }
});

var SameAsStudentAddressHandler = new Class({
    /*
     * Handles the actions associated with the "same as student address" 
     * checkboxes.
     */
    initialize: function(){
        this.update_address_field('1');
        this.update_address_field('2');
        
        $('id_guardian1_home_address_as_above').addEvent('change', function(){
            this.update_address_field('1');
        }.bind(this));
        $('id_guardian2_home_address_as_above').addEvent('change', function(){
            this.update_address_field('2');
        }.bind(this));
    },
    
    update_address_field: function(suffix) {
        /*
         * Changes the contents and appearance of the textareas when 
         * the checkboxes are changed.
         */
        var address_field_id = 'id_guardian'+suffix+'_home_address';
        var checkbox_id = address_field_id + '_as_above';
        var student_address_id = 'id_home_address';
        
        var same_as = ($(checkbox_id).checked);
        
        if (same_as) {
            // "Same as" button was checked - update the contents of the textarea and grey it out
            $(address_field_id).value = $(student_address_id).value;
            $(address_field_id).disabled = true;
        } else {
            // Unchecked. Reenable the textarea
            $(address_field_id).disabled = false;
        }
    }
});

var NationalitySwapper = new Class({
    /*
     * Adds a button to the admin page next to the nationality fields 
     * that when clicked swaps the values in the nationality and 
     * dual nationality field pairs around.
     */
    initialize: function() {
        // Add an element to trigger the swap
        button = new Element('a', { 'href':'#' })
                    .setText('Swap nationalities')
                    .setStyles({ 'position':'absolute', 'right':'80px', 'top':'5px' })
                    .addEvent('click', this.swap);
        
        // Put it alongside the dual nationality field
        $('field_dual_nationality').setStyle('position','relative');
        button.injectInside($('field_dual_nationality'));
    },
    
    swap: function() {
        // Swap the values in nationality and dual_nationality
        primary_value = $('id_nationality').getValue();
        $('id_nationality').setValue($('id_dual_nationality').getValue());
        $('id_dual_nationality').setValue(primary_value);
        // Swap the values in nationality_other and dual_nationality_other
        primary_value = $('id_nationality_other').getValue();
        $('id_nationality_other').setValue($('id_dual_nationality_other').getValue());
        $('id_dual_nationality_other').setValue(primary_value);
        
        $('id_nationality').fireEvent('change');
        $('id_dual_nationality').fireEvent('change');
    }
});
