/*
     $Revision$
     $Id$

     File:          fac_edit_widget_page.js
     Description:   clientside functions for fac_edit_widget_page.asp
*/

/* Config */
var MAX_COLS_PER_ROW = 6;
var TOTAL_GRID_WIDTH = 12;
var MAX_RAP_HEIGHT   = 1500;

/* Are filled onload */
var WIDGET_TITLE_HEIGHT;
var WIDGET_OUTER_X;
var WIDGET_OUTER_Y;

/* Are filled as soon as possible (onload if not hidden) */
var TOOLTIP_Y;
var ADD_ICON_Y;

var dragOptions,
    drOptions,
    resizeColumnOptions,
    resizeRowOptions;

function initOptions()
{
    dragOptions = {
        addClasses: false,
        containment: ".widget-body",
        opacity: 0.75,
        revert: true,
        revertDuration: 0,
        stack: ".widget-col-wrapper"
    }

    drOptions = {
        addClasses: false,
        tolerance: "pointer"
    }

    resizeColumnOptions = {
        containment: ".widget-body",
        create: resizeCreateColumn,
        handles: "e",
        start: resizeStartColumn
    }

    resizeRowOptions = {
        // containment: ".widget-body",
        minHeight: WIDGET_OUTER_Y + WIDGET_TITLE_HEIGHT,
        create: resizeCreateRow,
        handles: "s",
        start: resizeStartRow
    }
}

function clean_markers()
{
    var $markers = $(".wgt-marker");
    $markers.removeClass("wgt-marker");
    $markers.not(".widget-col-wrapper").remove();
}

function delete_widget()
{
    var $widgets_in_this_row = $(this).siblings(".widget-col-wrapper");
    var delete_width = parseInt($(this).attr("data-width"), 10);

    destroyEditMode();

    var widgets = $widgets_in_this_row.length;
    switch (widgets) {
        case 0:
            $(this).closest(".widget-container").remove(); // Enige widget in deze rij; verwijder hele rij
            break;
        case 1:
            updateColWidth($widgets_in_this_row, TOTAL_GRID_WIDTH);
            break;
        default: // 2+
            // Verwijderde breedte verdelen over de overgebleven widgets
            var add_width;
            for (var i = 0; i < Math.min(widgets, MAX_COLS_PER_ROW) && delete_width > 0; i++)
            {
                add_width = Math.ceil(delete_width / (widgets - i));
                delete_width -= add_width;
                updateColWidth($widgets_in_this_row.eq(i), add_width, true);
            }
            $(this).closest(".widget-container").addClass("editable");
            break;
    }

    $(this).remove();

    startEditMode();
}

function onDrop(e, ui)
{
    if (!ui.draggable.length)
        return;

    var contentCls = ".widget-col, .empty-col";

    var $orgWidget = $(contentCls, ui.draggable);
    var $newWidget = $(contentCls, e.currentTarget);

    var org_key = $orgWidget.closest(".widget-col-wrapper").attr("data-key");
    var new_key = $newWidget.closest(".widget-col-wrapper").attr("data-key");
    $orgWidget.closest(".widget-col-wrapper").attr("data-key", new_key);
    $newWidget.closest(".widget-col-wrapper").attr("data-key", org_key);

    $newWidget.replaceWith($orgWidget[0].outerHTML);
    $orgWidget.replaceWith($newWidget[0].outerHTML);

    $(".widget-col-wrapper").attr("style", ""); // jQuery draggable zet er een z-index op, maar die wil ik niet
}

function resizeColSize($elem, i)
{
    var changed = 0;
    $elem.removeClass(function (j, cls)
    {
        var currentClass = cls.match(/item-width-\d{1,2}/)[0];
        var currentSize = parseInt($elem.attr("data-width"), 10);

        var minSize = 1;
        var maxSize = TOTAL_GRID_WIDTH - $elem.nextAll(".widget-col-wrapper").length;

        changed = i > 0 ? Math.min(maxSize - currentSize, i) : Math.max(minSize - currentSize, i);
        var newSize = currentSize + changed;

        if (changed != i)
            console.error("zou niet meer voor moeten komen.");

        if (changed != 0) {
            $elem.addClass("item-width-" + newSize)
                 .attr("data-width", newSize);
            return currentClass; // delete old class
        }
    })
    return Math.abs(changed);

}

function resizeCreateColumn(e, ui)
{
    $("> div.ui-resizable-e", e.target).each(function () {
        // Create and style resize-icons (East)
        $(this).append(I("fa-ellipsis-v fa-lg", { fastyle: "far" }));
    });
}

var lastColWidth;
var stepSize;
function resizeStartColumn(e, ui)
{
    lastColWidth = ui.originalSize.width;

    // Recalc grid to 'snap' to
    var $this       = $(this);
    var $container  = $this.closest(".widget-container");
    var $nextColumn = $this.nextAll(".widget-col-wrapper:first");

    var widgetContainerWidth = $container.width();
    stepSize = (widgetContainerWidth - 100) / TOTAL_GRID_WIDTH;

    $resizable_cols.resizable("option", "grid", [stepSize]);

    /* Zet styling in resize-mode */
    $this.add($nextColumn).addClass("resizing-col-wrapper");

    // Recalc min & max width
    var minWidthInSteps = 1;
    var maxWidthInSteps = parseInt($(this).attr("data-width"), 10)      // Eigen breedte
                        + parseInt($nextColumn.attr("data-width"), 10)  // Breedte van volgende wgt
                        - minWidthInSteps;                              // Min-breedte van volgende wgt (altijd 1)

    var widgetMinWidth = Math.floor(minWidthInSteps * stepSize - 1);
    var widgetMaxWidth = Math.ceil(maxWidthInSteps * stepSize + 1);

    $(this).resizable("option", "minWidth", widgetMinWidth);
    $(this).resizable("option", "maxWidth", widgetMaxWidth);
}

function resizeColumn(e, ui)
{
    var storeLastColWidth = 1;
    if (parseFloat($(this).css("width")) <= 0)
    {
        $(this).css("width", lastColWidth);
        storeLastColWidth = 0;
    }

    var $next = $(this).nextAll(".widget-col-wrapper:first");
    var widgetContainerWidth = $(e.target).closest(".widget-container").width();
    stepSize = (widgetContainerWidth - 100) / TOTAL_GRID_WIDTH;

    var moveXcols = Math.round(Math.abs(ui.size.width - lastColWidth) / stepSize);
    if (ui.size.width > lastColWidth) // Moved right
    {
        resizeColSize($next, -moveXcols);
        resizeColSize($(this), moveXcols);
    }
    else if (ui.size.width < lastColWidth) // Moved left
    {
        resizeColSize($(this), -moveXcols);
        resizeColSize($next, moveXcols);
    }

    if (storeLastColWidth)
        lastColWidth = ui.size.width;
}

function resizeStopColumn(e, ui)
{
    var $resizedColumns = $(this).nextAll(".resizing-col-wrapper:first").addBack();

    /* Resize plattegronden */
    $resizedColumns.filter("[data-widget-type='FLR']").each(function () {
        var new_x = parseInt(stepSize * $(this).attr("data-width")) - WIDGET_OUTER_X;
        var img = $(this).find(".widget-type-flr > img")[0];
        resize_flr(img, new_x);
    });

    /* Zet styling in normal-mode */
    $resizedColumns.removeClass("resizing-col-wrapper").attr("style", ""); // jQuery resizable zet er een width op, maar doen wij zelf

    /* Reload widget on resize */
    var $widget_iframes = $resizedColumns.find(".widget-col iframe");
    $widget_iframes.each(function () {
        $(this).attr("src", $(this).attr("src"));
    });
}

function resizeCreateRow(e, ui)
{
    $("> div.ui-resizable-s", e.target).each(function () {
        var $fix_h = $('<input type="checkbox" class="fix">');
        if ($(this).closest(".widget-container").find(".widget-col-wrapper").filter("[data-height]").length)
            $fix_h.prop("checked", true); // Minimaal 1 hoogte gedefinieerd
        $(this).append(L("fac_widget_fix_height"))
               .append($fix_h)
               .append(I("fa-ellipsis-h fa-lg", { fastyle: "far" }));
    });
}

function resizeStartRow(e, ui)
{
    var hasAnyTitle = $(this).find(".widget-title").length;
    var minH = WIDGET_OUTER_Y + (hasAnyTitle ? WIDGET_TITLE_HEIGHT : 0);
    $(this).resizable("option", "minHeight", minH);
}

function checkRowClearance(container, rowMaxHeight)
{
    var $container = $(container);
    if (!$container.hasClass("widget-container")) // indien onload dan is dit de IFRAME of IMG
        $container = $container.closest(".widget-container");

    /* Set default waardes */
    if (!TOOLTIP_Y)
        TOOLTIP_Y = parseFloat($container.find(".widget-tooltip:last").height());
    if (!ADD_ICON_Y)
        ADD_ICON_Y = parseFloat($container.find(".empty-col").css("font-size")) * 4; // * 4 want het plus icoon heeft de fa-4x class

    var rowHeight = typeof rowMaxHeight === "undefined" ? 0 : rowMaxHeight;
    if (!rowHeight)
        $container.find("[class^=widget-type-").each(function () {
            if ($(this).hasClass(".widget-type-mk") || $(this).hasClass(".widget-type-mi"))
                rowHeight = Math.max(rowHeight, $(this).find("table").height());
            else
                rowHeight = Math.max(rowHeight, $(this).height());
        });

    var allWidgetsHaveTitles = $container.find("[class^=widget-type-]:first-child").length == 0;
    var titleOffset = allWidgetsHaveTitles ? WIDGET_TITLE_HEIGHT : 0;
    rowHeight += titleOffset;

    $container.find(".empty-col > i").removeAttr("style");

    // Voorkomt de tooltip als deze niet meer past
    $container.toggleClass("low-clearance", (TOOLTIP_Y > rowHeight));
    if (ADD_ICON_Y > rowHeight) // Als de plus niet meer in het vierkantje past, maken we hem kleiner
        $container.find(".empty-col > i").css("font-size", String(rowHeight) + "px");
}

function resizeRow(e, ui)
{
    $(e.target).find(".widget-col-wrapper").each(function () {
        var thisWidgetHasTitle = $(this).find(".widget-title").length;
        var wgt_h = parseInt(ui.size.height - (WIDGET_OUTER_Y + (thisWidgetHasTitle ? WIDGET_TITLE_HEIGHT : 0)), 10);
        $(this).find(".widget-size-value").text(wgt_h);
    });

    resizeRowContents.apply(e.target, [true, false, ui.size.height]);
}

function resizeRowContents(fixed_height, auto, height)
{
    fixed_height = fixed_height || false;
    var $container = $(this);
    var new_h = height || 0;
    if (typeof height === "undefined")
        $container.find("[class^=widget-type-]").each(function () {
            new_h = Math.max(new_h, parseInt($(this).height(), 10));
        });
    else
        new_h = height - WIDGET_OUTER_Y; /* == (afgerond) height incl widget-title */
    if (auto) // Alleen bij resizeStop
    {
        if (fixed_height)
            $container.find(".widget-col-wrapper").each(function() { $(this).attr("data-height", new_h); });
        else
        {
            $container.css("height", "auto") // Haal ingestelde hoogte weg
            $container.find(".widget-col-wrapper").each(function() { $(this).removeAttr("data-height"); });
        }
    }

    $container.find("[class^=widget-type-]").each(function () {
        var $widget = $(this);
        var new_height = height ? new_h - ($widget.prev(".widget-title").length ? WIDGET_TITLE_HEIGHT : 0) : new_h;
        switch ($(this).closest(".widget-col-wrapper").attr("data-widget-type"))
        {
            case "FAC": // Facilitor URL
            case "FAQ": // Kennisbank
            case "NWS": // Nieuwspagina
            case "RAP": // Rapportage
                // iFrame
                $widget.find("iframe").css("max-height", (fixed_height ? new_height : ""));
                var win = $widget.find("iframe")[0].contentWindow;
                if (win.FcltMgr)
                    win.FcltMgr.resized();
                if (auto && !fixed_height && $container.height() > MAX_RAP_HEIGHT) // Anders wordt die (default) wel heel erg groot bij het uitvinken
                {
                    $widget.find("iframe").css("max-height", "100vh");
                    if (win.FcltMgr)
                        win.FcltMgr.resized();
                }
                break;
            case "RAW": // HTML code
                if (fixed_height)
                    $widget.find("iframe").css("max-height", new_height);
                else
                    resize_raw($(this).find("iframe")[0]);
                break;
            case "URL": // Externe URL
                /* Geen access, dan mag je hem zelf mooi zetten. Dynamisch hier dus niet mogelijk */
                $widget.find("iframe")[0].height = (fixed_height ? new_height : ""); // Default 150px dus
                break;
            case "IMG": // Plaatje
                $widget.find("img").css("max-height", (fixed_height ? new_height : ""));
                break;
            case "FLR": // Plattegrond
                if (auto)
                {
                    var img = $widget.find("img")[0];
                    resize_flr(img, null, fixed_height ? new_height : -1);
                    $(this).closest(".widget-col-wrapper").nextAll(".ui-resizable-s").find(".fix").prop("checked", true);
                }
                break;
            case "MK": // Menukop
            case "MI": // Menuitem
                if (fixed_height)
                    $widget.css("max-height", new_height);
                else
                {
                    var actual_h = resize_menu($widget);
                    $widget.css("max-height", actual_h);
                }
                $widget.find("img").css("max-height", (fixed_height ? new_height : ""));
                break;
            default:
                console.error("Unknown widget-type (" + $(this).closest(".widget-col-wrapper").attr("data-widget-type") + ")");
                break;
        }
        checkRowClearance($container, new_h);
    })
}

function resize_menu(some_wrapping_div)
{
    return $(some_wrapping_div).find(".widget-type-mk > table, .widget-type-mi > table").height();
}

function resizeStopRow(e, ui)
{
    $(e.target).find(".fix").prop("checked", true);
    resizeRowContents.apply($(e.target), [true, true, ui.size.height]);
}

function updateColWidth($col_wrapper, new_width, relative)
{
    var old_width = parseInt($col_wrapper.attr("data-width"));
    if (relative)
        new_width += old_width;
    var sizeChanged = relative || new_width != old_width;
    $col_wrapper.removeClass(function (i, cls) { return cls.match(/item-width-\d{1,2}/) })
                .addClass("item-width-" + new_width)
                .attr("data-width", new_width);

    if (sizeChanged)
    {   /* Reload widget on resize */
        var $widget_iframe = $col_wrapper.find("iframe");
        $widget_iframe.attr("src", $widget_iframe.attr("src"));
    }
}

function upsert_widget_onpage_callback(params)
{
    if (params.delete)      // Verwijderen
    {
        delete_widget.apply($(".wgt-marker"));
        clean_markers();
        return;
    }
    else if (!params.key)   // Annuleren
    {
        clean_markers();
        return;
    }
    // else                    Aanpassen

    // Voor synchroniciteit in een eigen interne functie;
    function do_upsert_widget_onpage($container, $widget)
    {
        var $marker = $container.find(".wgt-marker");

        if ($marker.hasClass("widget-col-wrapper")) // Edit van bestaande widget
        {
            var width = $marker.attr("data-width");
            // Gebruik dan de width die de bestaande widget op de pagina heeft
            updateColWidth($widget, width);
            $marker.replaceWith($widget);
        }
        else                                        // Invoegen van nieuwe widget
        {
            $marker.replaceWith($widget);
            checkRowClearance($container);
            if ($container.children(".widget-col-wrapper").length >= MAX_COLS_PER_ROW)
                $container.removeClass("editable");
            // resize cols met de nieuwe erbij
            var cols = $container.children(".widget-col-wrapper").length;
            var totalWidth = TOTAL_GRID_WIDTH;
            $container.children(".widget-col-wrapper").each(function ()
            {
                newWidth = Math.round(totalWidth / cols);
                updateColWidth($(this), newWidth);
                cols--;
                totalWidth -= newWidth;
            });
        }

        startEditMode();
    }

    $.get("./fac_widget.asp?mode=edit&wgt_key=" + params.key, function (data)
    {
        if (!data)
            return;

        destroyEditMode();

        var $wgt_wrapper = $(".wgt-marker").closest(".widget-container");
        if ($wgt_wrapper.find(".big-tooltip").length)    // Nieuwe rij
        {
            clean_markers();
            var $new_row = $("<div class=\"widget-container editable\"></div>");
            $.get("./fac_widget.asp?mode=edit&wgt_key=-1", function (new_row_cols) { // -1 voor de vulling van een lege rij
                $new_row.append(new_row_cols);
                $wgt_wrapper.before($new_row);
                do_upsert_widget_onpage($new_row, $(data));
            });
        }
        else                                            // Bestaande rij
            do_upsert_widget_onpage($wgt_wrapper, $(data));
    });
}

var $resizable_cols = $();
var $resizable_rows = $();
var $draggables = $();
var $droppables = $();
function startEditMode()
{
    function init_resizable_cols() {
        $resizable_cols = $();
        $(".widget-container").each(function() {
            $resizable_cols = $resizable_cols.add($(this).children(".widget-col-wrapper").not(":last"));
        });
        $resizable_cols.resizable(resizeColumnOptions);
        $resizable_cols.on("resize", resizeColumn)
                       .on("resizestop", resizeStopColumn);
    }

    function init_resizable_rows() {
        $resizable_rows = $(".widget-container").not(":last");
        $resizable_rows.resizable(resizeRowOptions);
        $resizable_rows.on("resize", resizeRow)
                       .on("resizestop", resizeStopRow);
        $(".fix").on("change", function() {
            resizeRowContents.apply($(this).closest(".widget-container")[0], [$(this).prop("checked"), !$(this).prop("checked")]);
        });
    }

    function init_draggables() {
        $draggables = $(".widget-col-wrapper").not(".widget-new-wrapper");
        $draggables.draggable(dragOptions);
    }

    function init_droppables() {
        $droppables = $(".widget-col-wrapper").not(".widget-new-wrapper");
        $droppables.droppable(drOptions)
        $droppables.on("drop", onDrop);
    }

    $(".edit-widget").on("click", function() {
        clean_markers();
        $(this).closest(".widget-col-wrapper").addClass("wgt-marker");
        var wgt_key = parseInt($(this).closest(".widget-col-wrapper").attr("data-key"), 10);
        FcltMgr.openModalDetail("../mgt/fac_widget_onpage.asp?mode=edit&id=" + wgt_key, L("fac_widget"), { callback: upsert_widget_onpage_callback });
    });

    $(".delete-widget").on("click", function() {
        FcltMgr.confirm(L("fac_widget_del_txt"), delete_widget.bind($(this).closest(".widget-col-wrapper")));
    });

    $(".empty-col-wrapper").on("click", function() {
        clean_markers();
        $(this).prev(".filler-col-wrapper").before("<div class='wgt-marker'></div>");
        FcltMgr.openModalDetail("../mgt/fac_widget_onpage.asp?mode=edit&id=-1", L("fac_widget"), { callback: upsert_widget_onpage_callback });
    });

    init_resizable_cols();
    init_resizable_rows();
    init_draggables();
    init_droppables();
}

function destroyEditMode()
{
    $(".widget-icon").off();

    $(".empty-col-wrapper").off();

    $resizable_cols.resizable("destroy");
    $resizable_cols.off();
    $resizable_cols = $();

    $(".fix").off();
    $resizable_rows.resizable("destroy");
    $resizable_rows.off();
    $resizable_rows = $();

    $draggables.draggable("destroy");
    $draggables = $();

    $droppables.droppable("destroy")
    $droppables.off();
    $droppables = $();
}

$(function ()
{
    function _pixelTotal(computedStyle, cssProperties) {
        var result = 0;
        for (x in cssProperties)
            result += parseFloat(computedStyle[cssProperties[x]]);
        return result
    }

    var $dummyWrapper = $("<div>", { "class": "widget-col-wrapper item-width-1" });
    var $dummy =        $("<div>", { "class": "widget-col" }).appendTo($dummyWrapper);
    var $dummyTitle =   $("<div>", { "class": "widget-title" }).appendTo($dummy);
    $("<div>", { "class": "widget-type-fac" }).appendTo($dummy);

    $dummyWrapper[0].style.cssText = "position: absolute; left: -9999px; top: -9999px";
    $(".widget-container:last").append($dummyWrapper);

    var dummyStyle = window.getComputedStyle($dummy[0]);
    var titleStyle = window.getComputedStyle($dummyTitle[0]);

    WIDGET_TITLE_HEIGHT = _pixelTotal(titleStyle, ["height"]);
    WIDGET_OUTER_X = _pixelTotal(dummyStyle, ["marginLeft", "marginRight", "borderLeftWidth", "borderRightWidth"]);
    WIDGET_OUTER_Y = _pixelTotal(dummyStyle, ["marginTop", "marginBottom", "borderTopWidth", "borderBottomWidth"]);

    $dummyWrapper.remove();
    $dummyTitle     = null;
    $dummy          = null;
    $dummyWrapper   = null;

    // Deze hoeft maar 1x
    $(".widget-new-wrapper").on("click", function () {
        $(this).siblings(".empty-col-wrapper").eq(0).trigger("click");
    });

    $(".widget-container").each(function()
    {
        if ($(this).children(".widget-col-wrapper").length < MAX_COLS_PER_ROW)
        {
            $(this).addClass("editable");
        }
    });

    initOptions();
    startEditMode();

    $(".widget-type-mk, .widget-type-mi").each(function () {
        checkRowClearance(this);
    });
})