var Tsumiki = {
    /**
     *  Container Element ID (default "body" element).
     *  overwrite by variable "_tsumiki_targetid"
     */
    targetid: '',

    /**
     *  script directory
     *  overwrite by variable "_tsumiki_dir"
     */
    topdir: '',

    /**
     *  image file list
     *  overwrite by variable "_tsumiki_imagesrc"
     */
    imagesrc: ['blue.png', 'green.png', 'red.png', 'yellow.png', 'blue.png', 'green.png', 'red.png', 'yellow.png'],

    /**
     *  left offset for each browser
     *  overwrite by variable "_tsumiki_left_offset_ie" for IE
     */
    leftOffsetBrowser: 0,

    /**
     *  top offset for each browser
     *  overwrite by variable "_tsumiki_top_offset_ie" for IE
     */
    topOffsetBrowser: 0,

    // vars
    images: {},         // tsumiki images object
    data: {},           // tsumiki server data
    current: null,      // current d&d tsumiki
    flg_modify: false,  // upload flag

    /**
     *  initial
     */
    init: function() {
        // overwrite vars from out of this script
        if (typeof _tsumiki_targetid != 'undefined') Tsumiki.targetid = _tsumiki_targetid;
        if (typeof _tsumiki_dir != 'undefined') Tsumiki.topdir = _tsumiki_dir;
        if (typeof _tsumiki_imagesrc != 'undefined') Tsumiki.imagesrc = _tsumiki_imagesrc;

        // set offset pixel for IE
        if (navigator.userAgent.indexOf("MSIE") != -1) {
            if (typeof _tsumiki_left_offset_ie != 'undefined') Tsumiki.leftOffsetBrowser = _tsumiki_left_offset_ie;
            if (typeof _tsumiki_top_offset_ie != 'undefined') Tsumiki.topOffsetBrowser = _tsumiki_top_offset_ie;
        }

        // load images
        Tsumiki.setupImage();

        // setup element's events
        Event.observe(document.body, "mousemove", Tsumiki.move, false);
        Event.observe(document.body, "mouseup", Tsumiki.drop, false);

        // set timers.
        var timer1 = new PeriodicalExecuter(Tsumiki.loadData, 5);
        var timer2 = new PeriodicalExecuter(Tsumiki.uploadData, 1);

        // load tsumiki data.
        Tsumiki.loadData(true);
    },

    /**
     *  load images and append to container
     */
    setupImage: function() {
        var spaceie = "";
        for (var s = 0; s < Tsumiki.imagesrc.length * 3; s++) spaceie += " ";

        for (var i = 0; i < Tsumiki.imagesrc.length; i++) {
            var image = document.createElement("img");
            var imagesrc = Tsumiki.imagesrc[i];
            image.src = Tsumiki.topdir + "image/" + imagesrc;
            image.id = imagesrc + i;
            Tsumiki.data[image.id] = [];
            image.style.position = "absolute";
            image.style.width = image.width + "px";
            image.style.height = image.height + "px";
            image.pos = Tsumiki.pos;
            image.pos(50 + 50 * i, -1000, 1000 + i);
            Event.observe(image, "mousedown", Tsumiki.click, false);
            Event.observe(image, "contextmenu", function(event){Event.stop(event);}, false);
            if (Tsumiki.targetid && $(Tsumiki.targetid)) {
                $(Tsumiki.targetid).style.position = "relative";
                $(Tsumiki.targetid).appendChild(document.createTextNode(spaceie)); // For IE ?
                $(Tsumiki.targetid).appendChild(image);
            } else {
                document.body.appendChild(image);
            }
            Tsumiki.images[image.id] = image;
        }
    },

    /**
     *  update tsumiki positions
     */
    update: function() {
        // update positions by server data
        for (var id in Tsumiki.images) {
            var image = Tsumiki.images[id];
            var pos = [100, 50, 1000];
            if (Tsumiki.data[id] && Tsumiki.data[id].length == 3) {
                pos = Tsumiki.data[id];
            }
            image.pos(pos[0] + Tsumiki.leftOffsetBrowser, pos[1] + Tsumiki.topOffsetBrowser, pos[2]);
        }
    },

    /**
     *  load tsumiki positions from server
     */
    loadData: function(force) {
        if (!force && Tsumiki.flg_modify) {
            return;
        }
        var url = Tsumiki.topdir + "tsumiki.txt";
        url += "?" + (new Date()).getTime();
        var request = new Ajax.Request(
            url, 
            {
                method: 'get', 
                parameters: "", 
                onComplete: Tsumiki.dataLoaded
            });
    },

    /**
     *  upload tsumiki positions to server
     */
    uploadData: function() {
        if (!Tsumiki.flg_modify) {
            return;
        }
        if (Tsumiki.current) {
            return;
        }
        var url = Tsumiki.topdir + "update_tsumiki.php";
        var params = new Array();
        for (var id in Tsumiki.images) {
            var image = Tsumiki.images[id];
            var param = escape("tsumiki[" + id + "]");
            param += "=";
            param += escape((parseInt(image.style.left) - Tsumiki.leftOffsetBrowser) + "," + (parseInt(image.style.top) - Tsumiki.topOffsetBrowser) + "," + image.style.zIndex);
            params.push(param);
        }
        var request = new Ajax.Request(
            url, 
            {
                method: 'post', 
                parameters: params.join("&"), 
                onComplete: Tsumiki.dataLoaded
            });
    },

    /**
     *  retrieve tsumiki positions from server and update window
     */
    dataLoaded: function(request) {
        var posdata = request.responseText;
        if (posdata) {
            try {
                Tsumiki.data = eval("(" + posdata + ")");
            } catch (e) {
//                alert(e + "\n--------\n" + posdata);
            }
        }
        Tsumiki.update();
        Tsumiki.flg_modify = false;
    },

    /**
     *  event for tsumiki clicking
     */
    click: function(event) {
        Event.stop(event);
        var elem = Event.element(event);
        // right click to down z-position
        if ((event.button && event.button == 2)
            || (event.which && event.which == 3)) {
            elem.style.zIndex = 999;
            Tsumiki.resetZIndex();
            return;
        }
        // left click to d&d
        elem.style.zIndex = 1000 + Tsumiki.imagesrc.length + 1;
        Tsumiki.flg_modify = true;
        Tsumiki.current = elem;
    },

    /**
     *  event for tsumiki moving
     */
    move: function(event) {
        var image = Tsumiki.current;
        if (!image) {
            return true;
        }
        var leftOffset = 0;
        var topOffset = 0;
        if (Tsumiki.targetid && $(Tsumiki.targetid)) {
            var offset = Position.cumulativeOffset($(Tsumiki.targetid));
            leftOffset = offset[0];
            topOffset = offset[1];
        }
        image.pos(Event.pointerX(event) - image.width / 2 - leftOffset
                , Event.pointerY(event) - image.height / 2 - topOffset);
        Event.stop(event);
    },

    /**
     *  event for tsumiki dropping
     */
    drop: function(event) {
        if (Tsumiki.current) {
            Tsumiki.current = null;
            Tsumiki.resetZIndex();
        }
    },

    /**
     *  tsumiki object method for change position
     */
    pos: function(left, top, zIndex) {
        if (left != null) {
            this.style.left = left + "px";
        }
        if (top != null) {
            this.style.top = top + "px";
        }
        if (zIndex != null) {
            this.style.zIndex = zIndex;
        }
    },

    /**
     *  reset and align tsumiki z-position
     */
    resetZIndex: function() {
        var imageArray = [];
        for (var i in Tsumiki.images) {
            imageArray.push(Tsumiki.images[i]);
        }
        var sorter = function (x,y) {
                        return parseInt(x.style.zIndex) < parseInt(y.style.zIndex) ? -1 : 1;
                    };
        imageArray.sort(sorter);
        var new_images = {};
        for (var i = 0; i < imageArray.length; i++) {
            imageArray[i].style.zIndex = 1000 + i;
            new_images[imageArray[i].id] = imageArray[i];
        }
        Tsumiki.images = new_images;
    }
}
Event.observe(window, "load", Tsumiki.init, false);

