/*
# Copyright (C) 2009 Source Beyond
# http://www.sourcebeyond.com
# All rights reserved
#
*/

/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    JavaScript code shared accross multiple js files

    Documentation of code should follow the standards defined by:
    http://jsdoc.sourceforge.net/
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/

/* timeout for JQuery's ajax calls -  using a smaller timeout
here can cause broken pipe errors in django - be careful */
var AJAX_TIMEOUT = 9999999;

/* current media path */
var MEDIA_PATH = null;

/* array of symbols shared accross different areas */
var __bh_system_array;


function set_global_vars(options) {
    /*
    * All pages should call this function in order to setup
    * global accessible symbols
    *
    * @param {array} options Hash in the format:
    *                         {media_path: media path specified by
    *                                      BigHash in the format:
    *                                      /static_media or /url
    *                                      no slashes in the end}
    *
    * Note that more key-value pairs can be added by different
    * areas within the system. Add more keys by prefixing them
    * with the name of the file/app that is going to use it, e.g:
    * 'files_edit_after_upload_url'
    */
    MEDIA_PATH = options.media_path;

    //make the options array accessible from other callsites
    __bh_system_array = options;
}

function get_media_path() {
    /*
    * Returns the current registered media path
    * useful when fetching media files dynamically.
    * See set_global_vars for the format of the path returned by this
    * function
    *
    */
    return MEDIA_PATH;
}

function disable_submit(element) {
    /*
    * Disables a submit button (either input or button elements).
    * useful when submitting forms since it prevents odd errors
    * when clicking on the button twice by mistake.
    *
    * @param {object} element The button element
    */

    element.disabled = true;
    isub = (element.form.onsubmit ? (
                element.form.onsubmit() ? element.form.submit() : false
        ) : element.form.submit());
        if (isub == false) {
            element.disabled = false;
        };
    return isub;
}


function show_hide_element(element_selector, link_selector,
                           show_text, hide_text) {
    /*
    * Toggle the display of one ore more container elements
    *
    * @param {element_selector} a selector for one or more elements
    *                           to be displayed or hidden
    * @param {link_selector} a selector for an <a> element that triggers
    *                        the hide/show action
    * @param {show_text} text to be used as label for the <a> element
    *                    when the container elements are visible
    * @param {hide_text} text to be used as label for the <a> element
    *                    when the container elements are hidden
    *
    */
    var element, link_element, elements;
    if (!element_selector.match("#")) {
        elements = $("#" + element_selector);
        element = $("#" + element_selector + " :first")[0];
    } else {
        elements = $(element_selector);
        element = $(element_selector + " :first")[0];
    }

    if (!link_selector.match("#")) {
        link_element = $("#" + link_selector)[0];
    } else {
        link_element = $(link_selector)[0];
    }

  if(link_element.innerHTML == show_text) {
      elements.show();
      link_element.innerHTML = hide_text;
  } else {
      elements.hide();
      link_element.innerHTML = show_text;
  }
}


/*===========================================================
   AJAX
============================================================= */

$.ajaxSetup({
        scriptCharset: "utf-8" ,
        contentType: "application/json; charset=utf-8"
});


// always use this method instead of calling escape
// directly and be happy when handling unicode text
function custom_escape(value) {
    if (encodeURIComponent) {
        return encodeURIComponent(value);
    } else {
        return escape(value);
    }

}


function ajax_wrapper(options) {
    /*
     Use this function globaly instead of calling jQuery's functions
     directly.

     Options - expect a hash with the following arguments:
        -> request_type: must be GET or POST
        -> url: the ajax request's URL
        -> form_data: optional list of values to send to the server
                      within a POST request
        -> form_holder_id: the id of the form holder or form which
                           holds input widgets. This is only required
                           by POST requests
        -> form_holder_add_selector: a string representing Jquery selectors
                                     for additional form elements that must
                                     be used to fetch data for a post
                                     request. By default only :input will be
                                     used
        -> jquery_form_serialize: defines whether we can map a form with
                                  Jquery forms or not. This must be
                                  false if you want to avoid nested forms
        -> process_inputs: a callback which will be used to fetch values to
                           the inputs array. It expects two arguments:
                           e -> the form element itself
                           inputs -> an array which will store the
                                     form's data and will be sent
                                     within the POST request
        -> on_complete: a callback function that will be called when
                            the ajax request finishes. After success and
                            validation callbacks are finished. This callback
                            requires a 'request' argument
        -> on_success: a callback function that will be called when
                            the ajax request returns successfully.
                            This function must expect a 'r' argument
                            which is the data returned by the server.
                            ** This function will be called even when
                            there are validation errors.**
        -> on_validation_error: callback for validation errors
                            This function must expect a 'r' argument
                            which is the data returned by server.
        -> on_validation_success: callback called when there is no
                                  validation error. Expects a 'r' argument
                                  which is the data returned by server.
    */

      var form_data = null, abort_complete = false;
      var form_element, form_obj;

      $().ajaxError(function(event, request, settings){
            //var msg = "Server Error:\n" + settings.url;
            //ajax_debug_msg(msg);
       });


      if (!options.hide_status_area) {
          // setup ajax notification box
          /*
          var busy_element = $("#holder_ajax_status .notify_holder");
          if (options.status_msg) {
                $("#holder_ajax_status span").html(options.status_msg);
          } else {
                $("#holder_ajax_status span").html("Loading...");
          }

          function show_busy() {
             busy_element.show();
             busy_element.unbind("ajaxSend", show_busy);
          }

          function hide_busy() {
             busy_element.hide();
             busy_element.unbind("ajaxComplete", hide_busy);
          }

           busy_element.bind("ajaxSend", show_busy);
           busy_element.bind("ajaxComplete", hide_busy);
           */
      }

      if (options.form_holder_id) {
          form_element = options.form_holder_id;

          if (!options.jquery_form_serialize) {
                  var inputs = [];
                  var selector = form_element + " :input";
                  if (options.form_holder_add_selector) {
                        selector = selector + ", " + form_element + " " +
                            options.form_holder_add_selector;
                  }

                  $(selector).each(
                        function() {
                        if (options.process_inputs) {
                            options.process_inputs(this, inputs);
                        } else {
                            inputs.push(
                                this.name + '=' + custom_escape(this.value));
                        }
                  });
                  form_data = inputs.join('&');

          } else {
                form_obj = $(form_element);
                form_data = form_obj.formSerialize();
          }
      } else if (options.form_data) {
        form_data = options.form_data;
      }


      jQuery.ajax({
            type: options.request_type,
            url: options.url,
            datatype: "html",
            scriptCharset: "utf-8" ,
            contentType: "application/x-www-form-urlencoded; charset=utf-8",
            data: form_data,
            timeout: AJAX_TIMEOUT,

            complete: function(request, text_status) {
                 if (options.on_complete && !abort_complete) {
                    options.on_complete(request);
                 }
            },

            success: function(r) {
                if (r == "__forbidden__") {
                    abort_complete = true;
                    $("#ajax_forbidden_notification").show();
                    $("#ajax_forbidden_notification " +
                      "#ajax_forbidden_notification_denied").show();

                } else if (r == "__not_authenticated__") {
                    abort_complete = true;
                    $("#ajax_forbidden_notification").show();
                    $("#ajax_forbidden_notification "+
                      "#ajax_forbidden_notification_login").show();

                } else {
                     if (options.on_success) {
                        options.on_success(r);
                     }

                      if (r.match('class="errorlist"')) {
                        if (options.on_validation_error) {
                            options.on_validation_error(r);
                        }
                      } else {
                        if (options.on_validation_success) {
                            options.on_validation_success(r);
                        }
                      }
                }
            }
       });
}


