/*

(c) 2014 Michael Murtaugh and contributors to the Digital Publishing Toolkit

License: GPL3

This code has been developed as part of the [Digital Publishing Toolkit](http://digitalpublishingtoolkit.org).
with the support of Institute for [Network Cultures](http://networkcultures.org)
and [Creating 010](http://creating010.com).

*/

var editor_factory = aa_aceeditor(window.ace),
    editor = editor_factory.get_editor(),
    editor_elt = d3.select(editor.elt),
    cgi_url = d3.select("link[rel='cgi-url']").attr("href"),

    preview_div = d3.select("#editor")
        .append("div")
        .attr("class", "preview"),
    preview_iframe = preview_div
        .append("iframe"),

    make_div = d3.select("#editor")
        .append("div")
        .attr("class", "make"),
    make_body = make_div.append("div")
        .attr("class", "body"),
    make_icon = make_div
        .append("div")
        .attr("class", "icon"),
    make_gear = make_icon
        .append("div")
        .attr("class", "gear");


function url_for (script) {
    return cgi_url+script+"?p=" + encodeURIComponent(project);
}

function path_for_href (href) {
    var p = new RegExp("^/projects/([^/]+)/(.*)$"),
        m = href.match(p);
    if (m != null) {
        return m[2];
    }
}

editor.save(function (data) {
    console.log("save", data);
    $.ajax({
        url: url_for("save.cgi"),
        method: "post",
        data: {
            text: data.text,
            f: path_for_href(data.href)
        },
        dataType: "json",
        success: function (data) {
            // console.log("save.success", data);
            refresh_listing();
        },
        error: function (err) {
            console.log("save error", err);
        }
    })
});

make_body
    .append("div")
    .attr("class", "stdout");
make_body
    .append("div")
    .attr("class", "stderr");

make_gear.on("click", toggle_make);

var make_height = 300;

function open_make () {
    var cur_height = parseInt(make_div.style("height"));
    if (cur_height == 0) {
        make_div.style("height", make_height+"px"); 
    }
}

function close_make () {
    var cur_height = parseInt(make_div.style("height"));
    if (cur_height > 0) {
        make_div.style("height", 0); 
    }
}

function toggle_make () {
    var cur_height = parseInt(make_div.style("height"));
    if (cur_height > 0) {
        make_height = cur_height;
        make_div.style("height", 0); 
    } else {
        make_div.style("height", make_height+"px"); 
    }
}

aa_frames(document.getElementById("split"));

document.getElementById("editor").appendChild(editor.elt);

var activeURL;

function updateActiveItem () {
    var item = d3.selectAll("#listing div.item")
        .classed("active", function (d) {
            return d.url == activeURL;
        });
}

function edit (url, done, forceReload) {
    activeURL = url;
    editor.href(url, done, forceReload);
    editor.aceeditor.focus();
    editor_elt
        .style("display", "block");
    preview_div
        .style("display", "none");
    close_make();
    updateActiveItem();
    // make_div.style("display", "none");
}

function preview (url) {
    activeURL = url;
    preview_div
        .style("display", "block");
    editor_elt
        .style("display", "none");
    preview_iframe
        .attr("src", url);
    close_make();
    updateActiveItem();
    // make_div.style("display", "none");
}

function make (path, done) {
    // console.log("make", path);
    var make_url = url_for("make.cgi");
    make_busy(true);
    open_make();
    make_url += "&f="+encodeURIComponent(path);
    // 1. DRY-RUN TO SEE THE COMMAND THAT *WILL* HAPPEN NEXT
    // (and display it)
    d3.json(make_url+"&n=1", function (data) {
        d3.select("#editor .make .stdout").text(data.stdout);
        d3.select("#editor .make .stderr").text(data.stderr);
        if (data.returncode == 0) {
            // NOW MAKE FOR REAL
            d3.json(make_url, function (data) {
                console.log("make done", data);
                d3.select("#editor .make .stdout").text(data.stdout);
                d3.select("#editor .make .stderr").text(data.stderr);
                if (data.returncode == 0) {
                    close_make();
                }
                make_busy(false);
                refresh_listing(done); // nb done will get called with refresh data, not make data
            });
        }        
    })
}

function make_busy (val) {
    make_div.classed("busy", val);
}

function select_all () {
    d3.selectAll("#listing div.item").each(item_select);
    update_selection();
}

function delete_selection () {
    var items_selected = d3.selectAll("#listing div.selected"),
        num_selected = items_selected.size(),
        paths = items_selected.data().map(function (d) { return d.path });

    if (num_selected == 0) return;
    var ok = confirm("Delete "+num_selected+" selected file"+((num_selected==1)?"":"s") + "?");
    if (ok) {
        $.ajax({
             url: url_for("rm.cgi"),
             method: "post",
             data: {
                 'f[]': paths 
             },
             dataType: "json",
             success: function (data) {
                items_selected.each(item_deselect);
                update_selection();
                // console.log("rm response", data);
                refresh_listing();
             }
        });
    }
}

function download_selection () {
    var items_selected = d3.selectAll("#listing div.selected"),
        num_selected = items_selected.size(),
        paths = items_selected.data().map(function (d) { return d.path });

    if (num_selected == 0) return;
    var ok = true; //confirm("Download "+num_selected+" selected file"+((num_selected==1)?"":"s") + "?");
    if (ok) {
        var url = url_for("download.cgi");
        url += paths.map(function(x) { return "&f[]="+encodeURIComponent(x); }).join("");
        // console.log("download", url);
        preview_iframe
            .attr("src", url);

        items_selected.each(item_deselect);
        update_selection();
    }
}

var longclick_begin;

function item_select (d) {
    var elt = d3.select(this),
        eltwidth = $("a", this).width();
    elt
        .classed("selected", true)
        .select("input.itemcheckbox")
        .property("checked", true);
    if (d.exists) {
        elt
            .append("input")
            .attr("type", "text")
            .attr("class", "rename")
            .property("value", d.path)
            .style("width", eltwidth+"px");
        elt.select("a").classed("rename", true);        
    }
}

function item_deselect (d) {
    var elt = d3.select(this);
    elt
        .classed("selected", false)
        .select("input.itemcheckbox")
        .property("checked", false);
    elt.select("a").classed("rename", false);        
    elt
        .select("input.rename")
        .remove();
}

function checkbox_click (d) {
    var checked = d3.select(this).property("checked");
    if (checked) {
        d3.select(this.parentNode).each(item_select);
    } else {
        d3.select(this.parentNode).each(item_deselect);
    }
    update_selection();
}

function item_longclick(d) {
    d3.select(this.parentNode).each(item_select);
    update_selection();
}

function update_selection() {
    var items_all = d3.selectAll("#listing div.item"),
        items_selected = d3.selectAll("#listing div.selected"),
        numselected = items_selected.size(),
        selfunk = d3.select("#listing .selection_functions"),
        regfunk = d3.select("#listing .regular_functions");
    if (numselected >= 1) {
        selfunk.style("display", "inline");
        regfunk.style("display", "none");
    } else {
        selfunk.style("display", "none");
        regfunk.style("display", "inline")
    }
}

function listing_cancel () {
    d3.selectAll("#listing div.selected").each(item_deselect);
    update_selection();
}

function rename () {
    var ss = d3.selectAll("#listing a.rename"),
        frompaths = [],
        topaths = [];
    if (ss.size() == 0) {
        $("#listing .listing_rename_buttons").hide();
        return;
    }
    var ok = true; // confirm("Rename "+ss.size()+" file"+((ss==1)?"":"s") + "?");
    if (ok) {
        ss.each(function (d) {
            var newpath = d3.select(this.parentNode).select("input.rename").property("value");
            frompaths.push(d.path);
            topaths.push(newpath);
        });
        console.log("data", frompaths, topaths);
        $.ajax({
             url: url_for("mv.cgi"),
             method: "post",
             data: {
                 'f[]': frompaths,
                 't[]': topaths
             },
             dataType: "json",
             success: function (data) {
                // console.log("success", data);
                listing_cancel();
                refresh_listing();
             },
             error: function () {
                listing_cancel();
             }
        });
    } else {
        listing_cancel();
    }

}

function new_file () {
    d3.json(url_for("touch.cgi"), function (data) {
        refresh_listing();
    })
}

function refresh_listing(done) {
    d3.json(url_for("listing.cgi"), function (data) {
        // console.log("data", data);
        var div = d3.select("#listing .body");
            item = div
                .selectAll("div.item")
                .data(data.items, function (d) { return d.path });

        var newitem = item.enter()
                .append("div")
                .attr("class", "item");
        newitem
            .append("input")
            .attr("class", "itemcheckbox")
            .attr("type", "checkbox")
            .on("change", checkbox_click);
        newitem
            .append("a")
            .text(function(d) { return d.path })
            .attr("href", function (d) { return d.url })
            .on("click", function (d) {
                var that = this;
                d3.event.preventDefault();
                if (d3.select(this).classed("rename")) return;
                if (longclick_begin) {
                    click_time = new Date().getTime() - longclick_begin;
                    if (click_time > 700 && click_time < 2500) {
                        item_longclick.call(this, d);
                        return;
                    }
                }
                if (d.remake) {
                    // alert("make");
                    activeURL = d.url;
                    updateActiveItem();
                    make(d.path, function () {
                        // re-get the d in case of change!
                        var d = d3.select(that).datum();
                        // console.log("d", d, d.binary, d.url); 
                        if (!d.binary) {
                            // force reload!
                            console.log("force reload")
                            edit(d.url, null, true);
                        } else {
                            preview(d.url);
                        }
                    });
                    return false;
                } else if (!d.binary) {
                    edit(d.url);
                } else {
                    preview(d.url);
                }               
            })
            .on("mousedown", function () {
                longclick_begin = new Date().getTime();
            });
        // console.log("item.update", item);
        item
            .select("a")
            .classed("normal", function (d) { return d.exists && !d.remake })
            .classed("make", function (d) { return d.exists && d.remake })
            .classed("potential", function (d) { return !d.exists })
            .classed("exists", function (d) { return d.exists })
            .classed("remake", function (d) { return d.remake });

        item.exit()
            .remove();

        item.order();

        if (done) {
            done.call(data, data);
        }
    });
}
refresh_listing();

$("#listing .body").niceScroll({cursorcolor:"#0F0"});
$("#editor .make .body").niceScroll({cursorcolor:"#0F0"});

$("#listing_select_all").click(select_all);
$("#listing_refresh").click(refresh_listing);
$("#listing_delete").click(delete_selection);
$("#listing_download").click(download_selection);
$("#listing_rename").click(rename);
$("#listing_cancel").click(listing_cancel);
$("#listing_new_file").click(new_file);
// $("#listing_select_all").click(select_all);

/* File drop */

$(function () {
    $('#listing').fileupload({
        url: url_for("upload.cgi"),
        dataType: 'json',
        done: function (e, data) {
            refresh_listing();
            console.log(data.result);
            //$.each(data.result.files, function (index, file) {
            //    $('<p/>').text(file.name).appendTo(document.body);
            //});
        }
    });
});
