/*
     $Revision$
     $Id$

     File:        FcltJquery.js
     Description: Generieke functies die bij jquery wordt gebruikt.
     Parameters:
     Context:     Bestand wordt gelijktijdig geinclude met jquery.js in Shared/header.inc (Requires plugin)
     Note:

*/

// Let op: afterAction wordt alleen uitgevoerd als json.success gezet
function FcltCallbackAndThen(afterAction)
{
    return function (json, textStatus)
    {
        if (json.message) FcltMgr.alert(json.message);
        if (json.warning) FcltMgr.alert(json.warning);
        if (json.toaster) FcltMgr.topmanager().window.$.toast({ text: json.toaster, icon: "success", position : 'top-center', loaderBg: '#fff'});
        json.message = null;
        json.warning = null;
        json.toaster = null;
        if (json.success)
        {
            if (afterAction) afterAction(json);
        }
    }
};

function FcltCallbackAndThenAlways(afterAction)
{
    return function (json, textStatus)
    {
        if (json.message) FcltMgr.alert(json.message);
        if (json.warning) FcltMgr.alert(json.warning);
        if (json.toaster) FcltMgr.topmanager().window.$.toast({ text: json.toaster, icon: "success", position : 'top-center', loaderBg: '#fff'});
        json.message = null;
        json.warning = null;
        json.toaster = null;
        if (afterAction) afterAction(json);
    }
};

var FcltCallback = FcltCallbackAndThen(null);


var FcltCallbackRefresh = FcltCallbackAndThen(function ()
    {
      FcltMgr.reload();
    });

var FcltCallbackClose = FcltCallbackAndThen(function (json)
    {
      json.close = true;
      FcltMgr.closeDetail(window, json);
    });

var FcltCallbackDirtyLine = FcltCallbackAndThen(function (json)
    {
      // Bestaat json.key uit 1 of meerdere keys?
      if (json.key.indexOf(",") >= 0)
      {
        var key = json.key.split(",");
        for (var i = 0; i < key.length; i++)
        {
          $("#row" + key[i]).addClass('dirty');
        }
      }
      else
        $("#row" + json.key).addClass('dirty');
    });

// Roep met Ajax syncroon(!) een asp bestand aan en lever de JSON data op.
function FcltSyncgetJSON(url, data)
{
  var globalData;
  jQuery.ajax({ type: "GET",
                url: url,
                async: false,
                data: data,
                dataType: "json",
                success: function (data, textStatus) { globalData = data; globalData.textStatus = textStatus; }
              });
  if (globalData && globalData.warning)
    FcltMgr.alert(globalData.warning);
  if (globalData && globalData.error)
    FcltMgr.alert(globalData.error);
  if (globalData && globalData.toaster)
    FcltMgr.topmanager().window.$.toast({ text: globalData.toaster, icon: "success", position : 'top-center', loaderBg: '#fff'});;
  return globalData;
}

// Handig, komt heel veel voor
function gen_cancel()
{
    FcltMgr.closeDetail(window, { cancel: true } );
}

// TODO Alleen als Logging aan?
$.ajaxSetup(
    {"error":function(XMLHttpRequest,textStatus, errorThrown)
        {
            if (XMLHttpRequest.responseText.match(/^FCLTFriendly:/)) // Friendly tekst uit shared/500_error.asp
            {
                FcltMgr.alert(XMLHttpRequest.responseText.substring(13));
            }
            else if (XMLHttpRequest.responseText.match(/^FCLTExpired:/)) // Expired tekst uit common.inc
            {
                if (FcltMgr.getData('expired'))
                    FcltMgr.getData('expired')();
                else
                    FcltMgr.alert(XMLHttpRequest.responseText.substring(12));
            }
            else
            {
                FcltMgr.alert("JQuery Ajax Error: " + textStatus
                    + "\n" + XMLHttpRequest.status + ": " + XMLHttpRequest.statusText
                    + (errorThrown && errorThrown != XMLHttpRequest.statusText? "\n" + errorThrown:"")
                    + "\n\n" + this.type + " " + this.url
                    + "\n\n" + new Date().toLocaleString());
            }
        }
    });

// Experiment:
// Ctrl+W sluit onze eigen tabjes ipv browser tabjes?
// TODO: eigenlijk via FcltMgr._pageManager._closeTab(this)? Of juist niet?
// Je kunt nu ook je portal tabje sluiten. Is niet de bedoeling
//$(window).keydown(function(event)
//{
//     if (FcltMgr && event.ctrlKey && event.keyCode == 87) //  ctrl+W
//     {
//         FcltMgr.closeDetail();
//         event.preventDefault(); // Niet de *browser* tab
//     }
// });

// FIX FSN#22060 charset encoding probleem met $.getJSON en Ajax
// Mochten we ooit op utf8 overstappen dan kan dit er waarschijnlijk uit.
// http://forum.jquery.com/topic/serialize-problem-with-latin-1-iso-8859-1-and-solution
var myEncode = function (s)
{
    return unescape(encodeURIComponent(escape(s))).replace(/\+/g, "%2B");
}
jQuery.extend({
    param: function( a ) {
        var s = [];
        // If an array was passed in, assume that it is an array
        // of form elements
        if ( a.constructor == Array || a.jquery ){
            // Serialize the form elements
            jQuery.each( a, function(){
                s.push(myEncode(this.name) + "=" + myEncode(this.value));
            });
        }
        // Otherwise, assume that it's an object of key/value pairs
        else{
            // Serialize the key/values
            for ( var j in a )
                // If the value is an array then the key names need to be repeated
                if ( a[j] && a[j].constructor == Array )
                    jQuery.each( a[j], function(){
                        s.push(myEncode(j) + "=" + myEncode(this));
                    });
                else
                    s.push(myEncode(j) + "=" + myEncode(a[j]));
        }
        // Return the resulting serialization
        return s.join("&").replace(/ /g, "+");
    },

    serialize: function() {
        return this.param(this.serializeArray());
    }
});

// Voormalig jquery.autogrow-textarea.js
(function($) {

    /*
     * Auto-growing textareas; technique ripped from Facebook
     * JGL: modified shadow width ook goed doen als textarea (nog) invisible
     * JGL: modified with delayedUpdate
     */
    $.fn.autogrow = function(options) {

        this.filter('textarea').each(function() {

            var $this       = $(this),
                minHeight   = $this.height(),
                self        = this;

            var shadow = $('<div></div>').css({
                position:   'absolute',
                top:        -10000,
                left:       -10000,
                width:      Math.max(0,$(this).width() - parseInt($this.css('paddingLeft')) - parseInt($this.css('paddingRight'))),
                fontSize:   $this.css('fontSize'),
                fontFamily: $this.css('fontFamily'),
                lineHeight: $this.css('lineHeight'),
                resize:     'none'
            }).appendTo(document.body);

            var delayedUpdate = function() {
                if (self.timerID) clearTimeout(self.timerID);
                self.timerID = setTimeout( function () { update.apply(self) }, 250);
            }

            var update = function() {

                if (self.timerID) clearTimeout(self.timerID);
                var times = function(string, number) {
                    for (var i = 0, r = ''; i < number; i ++)
                    {
                        r += string;
                    }
                    return r;
                };

                var val = this.value.replace(/</g, '&lt;')
                                    .replace(/>/g, '&gt;')
                                    .replace(/&/g, '&amp;')
                                    .replace(/\n$/, '<br/>&nbsp;')
                                    .replace(/\n/g, '<br/>')
                                    .replace(/ {2,}/g, function(space) { return times('&nbsp;', space.length -1) + ' ' });

                shadow.html(val);
                shadow.css("width", Math.max(0,$(this).width() - parseInt($this.css('paddingLeft')) - parseInt($this.css('paddingRight'))));
                var oldheight = parseInt($(this).css('height'));
                var newheight = Math.max(shadow.height() + 20, minHeight);
                if (oldheight != newheight)
                {
                    $(this).css('height', newheight);
                    FcltMgr.resized(window);
                }

                /* Experimentele max-lengte indicatie onder label
                var len = this.value.length;
                var maxlen = parseInt(this.getAttribute("maxlength"), 10)||4000;
                var $lbl = $("label[for="+ this.name +"]");
                $lbl.find("div").remove();
                if ($lbl.length && len > maxlen * (90/100))
                {
                    if (len > maxlen)
                        $lbl.append("<div style='color:red;font-size:0.9em;'>Te lang.<br>Maximum is {0}, huidig is {1}</div>".format(maxlen, len));
                    else
                        $lbl.append("<div style='color:blue;font-size:0.9em'>{1}/{0} karakters</div>".format(maxlen, len));
                }
                */
            }

            $(this).change(delayedUpdate).keyup(delayedUpdate).keydown(delayedUpdate).blur(update);

            update.apply(this);

        });

        return this;

    }

})(jQuery);

jQuery.fn.filterByText = function(textbox, selectSingleMatch) {
  return this.each(function() {
    var select = this;
    var options = [];
    $(select).find('option').each(function() {
      options.push(this);
    });
    $(select).data('options', options);
    $(textbox).bind('change keyup', function() {
      var options = $(select).empty().scrollTop(0).data('options');
      var search = $.trim($(this).val()).toUpperCase();

      $.each(options, function(i) {
        var option = options[i];
        if($(option).text().toUpperCase().indexOf(search) > -1) {
          $(select).append(option);
        }
      });
      if (selectSingleMatch === true &&
          $(select).children().length === 1) {
        $(select).children().get(0).selected = true;
        $(select).children().trigger("change");
      }
    });
  });
};

// Add a clickable  sign after a select element that when clicked
// toggles the multiple attribute on the select box
(function($){

  $( document ).on('click', '.multi_select_toggle', function(e){
      e.stopPropagation();
      var sel_id = $(this).attr("fcltfor");
      var selector = $('select#' + sel_id);
      if (selector.length && selector[0].className.match(/^ui-/))
        return; // Afblijven van jQuery calendar jaar listboxje
      var old = selector.attr('multiple');
      selector.attr('multiple', !old);
      selector.attr('size', old?1:Math.min(selector.find("option").length, 8));
      $(e.target).html(old?'&raquo;':'&laquo;');
      FcltMgr.resized();
  })

  $.fn.extend({
    multiSelectToggle : function(options){
                            //Settings list and the default values
                            var defaults = {
                                label: '&raquo;'
                            };

                            var options = $.extend(defaults, options);
                            return this.each(function() {
                                    var lbl = $("<span fcltfor='" + this.id + "' class='multi_select_toggle' />").html(options.label);
                                    var div = $('<div />').addClass('multitoggle'); // deze div schuiven we 20px naar links
                                    $(this).wrap(div);
                                    $(this).before(lbl);
                                });
                          }
  });
  $(function () {
    $('select[fcltmulti=1]').multiSelectToggle();
  });

})(jQuery);

function fcltPrompt(title, defval, fnSuccess, params)
{
    params = params || "";
    $('<div></div>').appendTo('body')
        .html('<div>' + (params.hint||"") + '</div>'
              + "<input type='text' id='fcltPrompt' class='fld" + (params.required ? " required" : "" ) + "' value='" + defval + "'><br>"
              + "<label for='fcltPrompt_radio_T'><input type='radio' name='fcltTabs' id='fcltPrompt_radio_T' value='T' checked>"+params.data.textoptionT+"</label><br>"
              + "<label for='fcltPrompt_radio_M'><input type='radio' name='fcltTabs' id='fcltPrompt_radio_M' value='M'>"+params.data.textoptionM+"</label><br>"
             )
        .dialog({
            modal: true,
            title: title,
            zIndex: 10000,
            autoOpen: true,
            width: 'auto',
            resizable: false,
            buttons: [
                {
                    text: L("lcl_submit"),
                    click: function () {
                        if ($("#fcltPrompt").val() == "")
                        {
                            $("#fcltPrompt").addClass("missing");
                            FcltMgr.alert(L("lcl_shared_validator_missing"));
                        }
                        else
                        {
                            params.data.taboption = $("input[name=fcltTabs]:checked").val();
                            fnSuccess($("#fcltPrompt").val(), params.data);
                            $(this).dialog("close");
                        }
                    }
                },
                {
                    text: L("lcl_cancel"),
                    click: function () {
                        $(this).dialog("close");
                    }
                }
            ],
            close: function (event, ui) {
                $(this).remove();
            }
        });
}

function do_fcltfilters()
{   // Filters van opgeslagen tabjes verwerken
    if (window.fcltfilters && window.iface && window.fcltfilters != "null")
    {
        iface.stringToForm(window.fcltfilters, $('form[name=u2]'));
        var formObject = JSON.parse(window.fcltfilters);
        if ("columns" in formObject) // Dit is het hidden veld wat normaal meegesubmit wordt
        {                            // Werk de interface checkboxjes ook bij
            var colarr = formObject.columns.split(",");
            var grparr = formObject.groupby.split(",");
            $("#scfcolpicker tr").each(function()
            {
                if (!this.id)
                    return;
                var pos = $.inArray(this.id, colarr);
                if (pos > -1)
                {
                    $(this).find("input[type=checkbox]").prop("checked", true);
                    var selectgroup = $(this).find("select");
                    selectgroup.val(grparr[pos]);
                }
                else
                {
                    $(this).find("input[type=checkbox]").prop("checked", false);
                }

            });
        }
        if ("scf_pivot" in formObject) // Dit is het hidden veld wat normaal meegesubmit wordt
        {
            $("#chk_pivot").prop("checked", formObject.scf_pivot == 1)
        }
    }
}
$(function ()
    {
        setTimeout( do_fcltfilters, 250); // Heel klein beetje uitstellen zodat eventuele
                                          // suggests geinitialiseerd zijn
    }
  );

function updateTableHeaders() {
    $("div.divrstable").each(function() {

        var originalHeaderRow = $(".tableFloatingHeaderOriginal", this);
        var floatingHeaderRow = $(".tableFloatingHeader", this);

        // Copy row width from whole table
        floatingHeaderRow.css("width", originalHeaderRow.width());

        // Copy cell widths from original header cells
        var originalHeaderRowChildren = $(originalHeaderRow).find("TH, TD");

        $(floatingHeaderRow).find("TH, TD").each(function(index) {
            var cellWidth = originalHeaderRowChildren.eq(index).width();
            $(this).css('width', cellWidth);
        });

        var insideFrame = $(this).offset();
        var outsideFrame = $(window.frameElement).offset();

        var scrollTop = $(window.parent).scrollTop() + $(window).scrollTop();

        var offset = 0;
        if (insideFrame) offset += insideFrame.top;
        if (outsideFrame && $(window.parent).scrollTop() != 0) offset += outsideFrame.top;
        // if browser is IE then correct the top positioning
        var IEcorr = (/*@cc_on!@*/false)?-4:0;

        if ((scrollTop > offset) && (scrollTop < offset + $(this).height()))
        {
            originalHeaderRow.css("visibility", "visible");
            floatingHeaderRow.css("top", (IEcorr + Math.min(scrollTop - offset, $(this).height() - floatingHeaderRow.height())) + "px");

        }
        else
        {
            originalHeaderRow.css("visibility", "hidden");
            floatingHeaderRow.css("top", "0px");
        }
    });
}

$(function() {

    $("table:not(.tab_cat_sched) > thead").each(function() {
        $(this).parent("table").wrap("<div class=\"divrstable\" style=\"position:relative\"></div>");

        var originalHeaderRow = $(this);
        var clonedHeaderRow = originalHeaderRow.clone(true)
        originalHeaderRow.before(clonedHeaderRow);
        // if browser is IE then correct the left margin
        var IEcorr = (/*@cc_on!@*/false)?-2:1;
        clonedHeaderRow.addClass("tableFloatingHeader");
        clonedHeaderRow.css("position", "absolute");
        clonedHeaderRow.css("top", "0px");
        clonedHeaderRow.css("left", IEcorr);
        clonedHeaderRow.css("opacity", "0.90");

        originalHeaderRow.addClass("tableFloatingHeaderOriginal");
    });
    $(window).scroll(updateTableHeaders);
    $(window).resize(updateTableHeaders);
    $(window.parent).scroll(updateTableHeaders);
    $(window.parent).resize(updateTableHeaders);
    $('div.collapsed').on("click", updateTableHeaders);
    $('#autofilter').on("keyup", updateTableHeaders);
});

$(window).load(function() {
    updateTableHeaders();
});

$(window.parent).load(function() {
    updateTableHeaders();
});