// This file is part of Karesansui Core.
//
// Copyright (C) 2009 HDE, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// Authors:
//     Kei Funagayama <kei@karesansui-project.info>
//

if(typeof(jQuery) == "undefined"){
    document.write('<script type="text/javascript" src="${ctx.homepath}/static/lib/jquery.js"><\/script>');
}

// define
$.ajaxSetup({
    timeout: 0,
    beforeSend: _ajax_beforeSend,
    complete: _ajax_complete,
    error: _error,
    cache: true,
    async: false,
});

// private
function _ajax_notifications(msg){
    _part = '<div id="_ajax1_lock" style="position: absolute; right: 0px; top: 0px; background-color:#FF6D64;"><span class="_ajax_lock_value">' + msg + '</span></div>';
    $("#ajax").html(_part);
    $("#_ajax_lock").click(function(){
        $("#_ajax_lock").html('');
    });
}

function _ajax_alert_on(status, msg){
    if($(".grayout-alert").hasClass("grayout-alert") == true){
        alert_on(".grayout-alert", status, msg);
        adjust_grayout_screen();
    } else if($(".alert").hasClass("alert") == true){
        alert_on(".alert", status, msg);
    } else {
        _ajax_notifications(msg);
    }
}

function _ajax_alert_off(){
    if($(".grayout-alert").hasClass("grayout-alert") == true){
        alert_off(".grayout-alert");
    } 
    if($(".alert").hasClass("alert") == true){
        alert_off(".alert");
    }
    _ajax_notifications("");
}

function _ajax_beforeSend(XMLHttpRequest){
    $("#traffic").attr('src', "${ctx.homepath}/static/images/access.gif");

    _ajax_alert_off();
}

function _ajax_complete(XMLHttpRequest, textStatus){
    $("#traffic").attr('src', "${ctx.homepath}/static/images/access-off.gif");

    if(XMLHttpRequest.status == "202"){
        _ajax_alert_on("SUCCEED", "${_('Accepted')}" + " [" + XMLHttpRequest.status + "]");
    } else if(XMLHttpRequest.status == "204"){
        _ajax_alert_on("ERROR", "${_('No Content')}" + " [" + XMLHttpRequest.status + "]");
    }
}

function _error(xml_http_request, status, e){
    if('error' == status) {
        _ajax_notifications("${_('Ajax Status: Error')}");
    } else if('notmodified' == status){
        _ajax_notifications("${_('Ajax Status: Not Modified')}");
    } else if('timeout' == status){
        _ajax_notifications("${_('Ajax Status: Timeout')}");
    } else if('parsererror' == status){
        _ajax_notifications("${_('Ajax Status: Parse Error')}");
    }    

    if(xml_http_request.status == "400"){
        _ajax_alert_on("ERROR", "${_('Bad Request')}" + " [" + xml_http_request.status + "]\n" + xml_http_request.responseText);
    }else if(xml_http_request.status == "404"){
        _ajax_alert_on("ERROR", "${_('Not Found')}" + " [" + xml_http_request.status + "]\n" + xml_http_request.responseText);
    }else if(xml_http_request.status == "405"){
        _ajax_alert_on("ERROR", "${_('Method Not Allowed')}" + " [" + xml_http_request.status + "]");
    }else if(xml_http_request.status == "409"){
        _ajax_alert_on("ERROR", "${_('Conflict')}" + " [" + xml_http_request.status + "]\n" + xml_http_request.responseText);
    }else{
        _ajax_alert_on("ERROR", "${_('Illegal Error')}");
    }
}

function _ajax_beforSend_grayout(id, url, params_form, validator, async_flag, ajax_event){
    var check = validator();
    if(!check){
        $(id).one("click", ajax_event(id, url, params_form, validator, async_flag));
    }
    return check;
}

function _ajax_success_grayout(){
    alert_on(".grayout-alert", "SUCCEED", "${_('Update success.')}");
    $(".grayout-contents :input").attr("disabled", "disabled");
    $(".grayout-footer span.button-right").html("${_('Close')}");

    // for ajax_post(put)_grayout function
    $(".grayout-footer a").unbind("click");
    
    $("#cluetip").hide();
    $('span[id$="_help"]').each(function(){
        $(this).remove();
    })

    $(".grayout-footer a").attr("id", "grayout_close_button");
    $("#grayout_close_button span").removeClass("onclick");
    grayout_submit_effect("#grayout_close_button");
    $("#grayout_close_button").one("click", function(){
        grayout_close();
    });
}

function _ajax_complete_grayout(XMLHttpRequest, textStatus){
    _ajax_complete(XMLHttpRequest, textStatus);
    adjust_grayout_screen();
}

function _ajax_error_grayout(xml_http_request, status, e,
                             id, url, params_form, validator, async_flag, ajax_event){
    _error(xml_http_request, status, e);
    $(id + " span").removeClass("onclick");
    $(id).one("click", ajax_event(id, url, params_form, validator, async_flag));
}

function _check_file_upload(response){
    var ret = true;
    res_arr = response.split(/\n/);
    for(var i = 0; i < res_arr.length; i++){
        var data_arr = res_arr[i].split(/:/);
        if(data_arr[0] == "400" || data_arr[0] == "409" || data_arr[0] == "500"){
            ret = false;
            break;
        }
    }
    return ret;
}

function _ajax_file_delete(form_id, upload_button_id, cancel_button_id, \
                           name_input_id, value_input_id, url, validates, async_flag){
    $(upload_button_id).hide();
    $(cancel_button_id).show();

    $(upload_button_id).unbind("click");

    $(cancel_button_id).one("click", function(){
        $.ajax({
            url: url + "/" + $(name_input_id).val(),
            data: null,
            dataType: "html",
            type: "DELETE",
            async: async_flag,
            
            beforeSubmit: function(){
                validates();
            },
            success: function(data, status){
                $(value_input_id).attr("disabled", "");
                $(name_input_id).attr("value", "");

                _ajax_alert_on("CAUTION", "${_('Succeeded to remove the file.')}");
                _ajax_file_upload(
                    form_id, 
                    upload_button_id, 
                    cancel_button_id, 
                    name_input_id, 
                    value_input_id, 
                    url, 
                    validates,
                    async_flag
                );
            },
            error: function(xml_http_request, status, e){
                _error(xml_http_request, status, e);
                adjust_grayout_screen()
                _ajax_file_delete(
                    form_id,
                    upload_button_id,
                    cancel_button_id,
                    name_input_id,
                    value_input_id,
                    url,
                    validates,
                    async_flag
                );
            },
            complete: function(xml_http_request, text_status){
                _ajax_complete(xml_http_request, text_status);
                adjust_grayout_screen();
            }
        });
    });
}

function _ajax_file_upload(form_id, upload_button_id, cancel_button_id, \
                           name_input_id, value_input_id, url, validates, async_flag){
    var options = {
        beforeSubmit: function(){
            validates();
        },
        url: url,
        async: async_flag,

        success: function(data, status){
            if(_check_file_upload(data) == true){
                // success
                var real_filename = data;
                $(value_input_id).attr("disabled", "disabled");
                $(name_input_id).attr("value", data);

                _ajax_alert_on("CAUTION", "${_('Succeeded to update the file.')}" + "\n" + "${_('To complete the set, please click on the button below the screen.')}");
                adjust_grayout_screen()

                _ajax_file_delete(
                    form_id, 
                    upload_button_id, 
                    cancel_button_id, 
                    name_input_id, 
                    value_input_id, 
                    url, 
                    validates,
                    async_flag
                );
            } else {
                // error
                _ajax_alert_on("ERROR", "${_('Failed to create icon file')}");
                adjust_grayout_screen()
                $(upload_button_id).one("click", function(){
                    $(form_id).submit()
                });
            }
        },
        error: function(xml_http_request, status, e){
            _error(xml_http_request, status, e);
            adjust_grayout_screen()
            $(upload_button_id).one("click", function(){
                $(form_id).submit()
            });
        },
        complete: function(xml_http_request, text_status){
            _ajax_complete(xml_http_request, text_status);
            adjust_grayout_screen();
        }
    }
    $(form_id).ajaxForm(options); 

    $(upload_button_id).show();
    $(cancel_button_id).hide();

    $(upload_button_id).one("click", function(){
        $(form_id).submit()
    });
    $(cancel_button_id).unbind("click");
}

// lib
function ajax_request(url, data, callback, type, method, async_flag){
    if($.isFunction(data)) {
        callback = data;
        data = {};
    }
    async_flag = set_async_flag(async_flag);

    return $.ajax({
        url: url,
        data: data,
        dataType: type,
        type: method,
        async: async_flag,
        
        success: callback
    });
}

$.extend({
    put: function(url, data, callback, type, async_flag) {
        return ajax_request(url, data, callback, type, 'PUT', async_flag);
    },
    remove: function(url, data, callback, type, async_flag) {
        return ajax_request(url, data, callback, type, 'DELETE', async_flag);
    }
});

// public 
function ajax_get(id, url, params, async_flag){
    async_flag = set_async_flag(async_flag);

    $.ajax({
        url: url,
        data: params,
        type: "GET",
        async: async_flag,

        success: function(data, status) {
            if(data != ""){
                $(id).html(data);
            }
        }
    });
}

function ajax_delete(id, url, params, async_flag){
    async_flag = set_async_flag(async_flag);

    $.ajax({
        url: url,
        data: params,
        type: "DELETE",
        async: async_flag,

        success: function(data, status) {
            if(data != ""){
                $(id).html(data);
            }
        }
    });
}

function ajax_json(url, params, fn, async_flag){
    async_flag = set_async_flag(async_flag);

    $.ajax({
        url: url,
        data: params,
        dataType: "json",
        type: "GET",
        async: async_flag,
        success: fn
    });
    return false;
}

function ajax_post_event(id, url, params_form, validator, async_flag){
    async_flag = set_async_flag(async_flag);
    
    grayout_submit_effect(id);
    $(id).one("click", function() {
        $.ajax({
            url: url,
            data: $(params_form).serialize(),
            dataType: "html",
            type: "POST",
            async: async_flag,
            
            beforeSend: function(){
                return _ajax_beforSend_grayout(id, url, params_form, validator, async_flag, ajax_post_event);
            },
            success: _ajax_success_grayout,
            complete: _ajax_complete_grayout,
            error: function(xml_http_request, status, e){
                _ajax_error_grayout(xml_http_request, status, e,
                                        id, url, params_form, validator, async_flag, ajax_post_event);
            }
        });
    });
}

function ajax_put_event(id, url, params_form, validator, async_flag){
    async_flag = set_async_flag(async_flag);

    /*
        Problem:
        IE8 throw PUT request and receive seeother, that has location current URI,
        IE8 continue  throw PUT request endlessly.

        Solution:
        use overload POST method or redirect other URI.
    */
    /* overload POST */
    method_type = "PUT";
    if(jQuery.browser.msie){
        $("#_method").val("PUT");
        method_type = "POST";
    }

    grayout_submit_effect(id);
    $(id).one("click", function() {
        $.ajax({
            url: url,
            data: $(params_form).serialize(),
            dataType: "html",
            type: method_type,
            async: async_flag,
            
            beforeSend: function(){
                 return _ajax_beforSend_grayout(id, url, params_form, validator, async_flag, ajax_put_event);
            },
            success: _ajax_success_grayout,
            complete: _ajax_complete_grayout,
            error: function(xml_http_request, status, e){
                _ajax_error_grayout(xml_http_request, status, e,
                                    id, url, params_form, validator, async_flag, ajax_put_event);
            }
        });
    });
}

function set_async_flag(async_flag){
    if(async_flag != true){
        async_flag = false;
    }
    return async_flag;
}
