// Copyright 2008-2011 Andrey Zholos. All rights reserved.

/* Map class */

function Map() {
}

// Tile
Map.prototype.T = function(x, y) {
    this.x = x;
    this.y = y;
}

// Image
Map.prototype.I = function(s) {
    this.s = s; // src
}

Map.prototype.I.prototype.d = function(px, py) {
    if (this.ed) {
        var d = this.ed.parentNode ? this.ed.cloneNode(false) : this.ed;
        d.style.opacity = "";
    } else {
        var d = createElement("div");
        d.style.position = "absolute";
        d.style.width = this.w + "px";
        d.style.height = this.h + "px";
        d.style.marginLeft = -this.cx + "px";
        d.style.marginTop = -this.cy + "px";
        d.style.backgroundImage = "url(" + encodeURI(this.s) + ")";
        d.style.backgroundRepeat = "no-repeat";
        this.ed = d;
    }
    d.style.left = px + "px";
    d.style.top = py + "px";
    return d;
}

Map.prototype.I.prototype.i = function(px, py) {
    // similar method in desktop.js
    if (this.ei) {
        var i = this.ei.parentNode ? this.ei.cloneNode(false) : this.ei;
        i.style.opacity = "";
    } else {
        var i = createElement("img");
        i.setAttribute("src", this.s);
        i.style.display = "block";
        i.style.position = "absolute";
        //i.style.width = this.w + "px";
        //i.style.height = this.h + "px";
        i.style.marginLeft = -this.cx + "px";
        i.style.marginTop = -this.cy + "px";
        this.ei = i;
    }
    i.style.left = px + "px";
    i.style.top = py + "px";
    return i;
}

Map.prototype.I.prototype.m = function() {
    if (!this.mm) {
        this.mm = [];
        var m = function(i) {
            var request = requestObject();
            request.onreadystatechange = function() {
                if (request.readyState == 4 && request.status == 200) {
                    var m = request.responseText.split('\n');
                    if (m.pop() == "" && m.length == i.h && m[0].length == i.w) {
                        m.splice(0, 0, 0, i.mm.length);
                        [].splice.apply(i.mm, m);
                    } else
                        i.mm.splice(0, 0, ".");
                }
            }
            request.open("GET", i.s.replace(/\.png$/, "") + ".mask");
            request.send(null);
        }
        m(this);
        m = function(i, m) { return function() { if (!i.mm) m(i); } }(this, m);
        setTimeout(m, 2500);
        setTimeout(m, 10000);
    }
    return this.mm;
}

// Sprite
Map.prototype.S = function(t) {
    this.t = t; // tag
    this.il = []; // images
}

Map.prototype.S.prototype.i = function(va) {
    return this.il[(va + 11) % this.il.length];
}

// Object
Map.prototype.O = function(t) {
    this.t = t; // tag
}

Map.prototype.O.prototype.i = function(ol, eo) {
    var k = ol.length;
    if (k >= 7) {
        for (var j = 1; j << 1 <= k; j <<= 1);
        for (var l = -1; j; j >>= 1)
            if (l + j < k && this.py >= ol[l + j].py)
                l += j;
        l += 1;
    } else
        for (var l = 0; l < k; l++)
            if (this.py < ol[l].py)
                break;
    if (l < k)
        eo.insertBefore(this.ei, ol[l].ei);
    else
        eo.appendChild(this.ei);
    ol.splice(l, 0, this);
}

Map.prototype.O.prototype.d = function(ol, eo) {
    eo.removeChild(this.ei);
    ol.splice(ol.indexOf(this), 1);
}

Map.prototype.O.prototype.m = function(pyo, ol, eo) {
    var l = ol.indexOf(this);
    if (this.py < pyo) {
        if (l > 0 && ol[l - 1].py > this.py)
            for (var i = l - 1; i >= 1; i--)
                if (ol[i - 1].py <= this.py) {
                    eo.insertBefore(this.ei, ol[i].ei);
                    ol.splice(l, 1);
                    ol.splice(i, 0, this);
                    break;
                }
    } else {
        if (l < ol.length - 1 && ol[l + 1].py < this.py)
            for (var i = l + 2;; i++)
                if (i == ol.length) {
                    eo.appendChild(this.ei);
                    ol.splice(l, 1);
                    ol.push(this);
                    break;
                } else if (ol[i].py > this.py) {
                    eo.insertBefore(this.ei, ol[i].ei);
                    ol.splice(i, 0, this);
                    ol.splice(l, 1);
                    break;
                }
    }
}

// Map
Map.prototype.reset = function() {
    this.tc = []; // tiles by coordinates
    this.tl = []; // displayed tiles by depth
    this.ot = []; // objects by tags
    this.ol = []; // displayed objects by depth
    this.lo = {}; // lingering object tags
    this.sl = []; // list of sprites keyed by tag
    this.il = []; // list of images by src

    // base element
    this.div.style.overflow = "hidden";
    removeChildren(this.div);
    if (this.evdiv != this.div) {
        registerEventHandler(this.div, "click", function(ms) { return function(ev) { ms.evc(ev); }; }(this));;
        registerEventHandler(this.div, "mousemove", function(ms) { return function(ev) { ms.evm(ev); }; }(this));
        registerEventHandler(this.div, "mousedown", function(event) { event.preventDefault(); }); // default is to drag, which is not helpful
        this.evdiv = this.div;
    }
    if (this.bodyevk)
        this.bodyevk.unregister();
    this.bodyevk = registerEventHandler(document, "keydown", function(ms) { return function(ev) { ms.evk(ev); }; }(this));

    // tiles layer
    this.et = createElement("div");
    this.et.style.position = "absolute";
    this.et.style.left = "50%";
    this.et.style.top = "50%";
    this.et.style.width = "0px";
    this.et.style.height = "0px";
    this.div.appendChild(this.et);

    // objects layer
    this.eo = createElement("div");
    this.eo.style.position = "absolute";
    this.eo.style.left = "50%";
    this.eo.style.top = "50%";
    this.eo.style.width = "0px";
    this.eo.style.height = "0px";
    this.div.appendChild(this.eo);

    // effects layer
    this.ee = createElement("div");
    this.ee.style.position = "absolute";
    this.ee.style.left = "50%";
    this.ee.style.top = "50%";
    this.ee.style.width = "0px";
    this.ee.style.height = "0px";
    this.div.appendChild(this.ee);

    // tooltip layer
    this.ep = createElement("div");
    this.ep.style.position = "absolute";
    this.ep.style.padding = "5px";
    this.ep.style.visibility = "hidden";
    this.ep.style.backgroundColor = "#bbb";
    this.ep.style.opacity = "0.8";
    this.div.appendChild(this.ep);

    // debug layer
    this.edebug = createElement("div");
    this.edebug.style.backgroundColor = "white";
    this.edebug.style.position = "absolute";
    this.edebug.style.left = "-.5em";
    this.edebug.style.top = "-.5em";
    this.edebug.style.padding = ".3em";
    this.edebug.style.opacity = "0.8";
    this.edebug.style.fontSize = "8pt";
    this.edebug.style.fontWeight = "bold";
    this.div.appendChild(this.edebug);

    this.va = 12; // view angle
    this.rd = 20.25; // tile radius
    this.spfS();
    this.centerx = this.centery = 0;
    this.centerc = true;

    this.efsl = []; // sliding objects, don't set to disable
    this.effd = []; // fading objects, don't set to disable
    this.efmsl = {}; // sliding map layer, don't set to disable
    this.efhl = []; // highlighted tiles, don't set to disable
}


var up;

Map.prototype.efT = function(state, t) {
    // state: 1 = first, 2 = last

    if (!state && this.eft != t)
        return;

    var rep = 0;
    if (this.efsl) {
        for (var h = 0, m = this.efsl.length; h < m;) {
            var o = this.efsl[h];

            var pyo = o.py;
            var dx = Math.abs(o.efpx - o.px);
            var dy = Math.abs(o.efpy - o.py);
            if (state == 2 || dx <= 3 && dy <= 3) {
                o.px = o.efpx;
                o.py = o.efpy;
                delete o.efpx;
                delete o.efpy;
                this.efsl.splice(h, 1);
                m--;
            } else {
                var dd = Math.sqrt(dx * dx + dy * dy);
                var fc = dd >= 15 ? 12 / dd : .8;
                o.px += Math.round(fc * (o.efpx - o.px));
                o.py += Math.round(fc * (o.efpy - o.py));
                h++;
            }

            o.ei.style.left = o.px + "px";
            o.ei.style.top = o.py + "px";
            o.m(pyo, this.ol, this.eo);
        }
        if (m > 0)
            rep = 1;
    }

    if (this.effd) {
        for (var h = 0, m = this.effd.length; h < m;) {
            var o = this.effd[h];

            var od = Math.abs(o.efoc - o.efot);
            if (state == 2 || od <= .1) {
                this.effd.splice(h, 1);
                m--;

                if (o.efot == 0)
                    o.d(this.ol, this.eo);
                else
                    o.ei.style.opacity = "";

                delete o.efoc;
                delete o.efot;
            } else {
                var d = o.efot > o.efoc ? 1 : -1;
                o.efoc += (od > .3 ? .3 : od) * d;
                o.ei.style.opacity = "" + o.efoc;
                h++;
            }
        }
        if (m > 0)
            rep = 1;
    }

    if (this.efmsl) {
        if (this.efmsl.nx != undefined && this.efmsl.ny != undefined) {
            var d = Math.sqrt(Math.pow(this.efmsl.nx - this.efmsl.cx, 2) + Math.pow(this.efmsl.ny - this.efmsl.cy, 2));
            var g = Math.sqrt(d);
            var s = this.efmsl.s || 0;
            this.efmsl.s = s = s + 1 < g ? s + 1 : s - .5 > g ? s - .5 : g;
            if (state != 0)
                s = 0;
            if (d > 2 && s < d) {
                this.efmsl.cx += s / d * (this.efmsl.nx - this.efmsl.cx);
                this.efmsl.cy += s / d * (this.efmsl.ny - this.efmsl.cy);
                this.efmsl.b = true;
                rep = rep || 2;
            } else {
                this.efmsl.cx = this.efmsl.nx;
                this.efmsl.cy = this.efmsl.ny;
                delete this.efmsl.nx;
                delete this.efmsl.ny;
                delete this.efmsl.s;
            }
            this.et.style.left = Math.round(this.efmsl.cx) + "px";
            this.et.style.top = Math.round(this.efmsl.cy) + "px";
            this.eo.style.left = Math.round(this.efmsl.cx) + "px";
            this.eo.style.top = Math.round(this.efmsl.cy) + "px";
            this.ee.style.left = Math.round(this.efmsl.cx) + "px";
            this.ee.style.top = Math.round(this.efmsl.cy) + "px";
        }
    }

    if (this.efhl && this.efhl.length != 0) {
        this.efhlo = ((this.efhlo || 0) + 3) % 100;
        var opacity = state == 2 ? "" : "" + (1 - .01 * Math.abs(50 - this.efhlo));
        if (state || this.efhlo % (this.efhl.length < 40 ? 1 : this.efhl.length < 120 ? 5 : 11) == 0)
            for (var i = 0; i < this.efhl.length; i++)
                this.efhl[i].ed.style.opacity = opacity;
        rep = rep || 2;
    }

    if (rep) {
        if (state == 1)
            t = this.eft = (new Date).getTime();
        this.eftw = rep != 2;
        setTimeout(function(ms) { return function() { ms.efT(0, t); }; }(this), 50);
    } else {
        delete this.eft;
        delete this.eftw;
    }
}

Map.prototype.spfS = function() {
    var alpha = (this.va * 30 - 255) * Math.PI / 180;
    var sin35 = Math.sin(35 * Math.PI / 180);
    var sqrt3 = Math.sqrt(3);
    var sin = Math.sin(alpha);
    var cos = Math.cos(alpha);
    var r = this.rd * sqrt3;
    var a = (sqrt3 * cos - sin) / 2 * r;
    var b = -(sqrt3 * sin + cos) / 2 * r * sin35;
    var c = -sin * r;
    var d = -cos * r * sin35;
    var round = Math.round;

    this.spx = function(a, c) { return function(u, v) { return round(a * u + c * v); }; }(a, c);
    this.spy = function(b, d) { return function(u, v) { return round(b * u + d * v); }; }(b, d);

    var det = a * d - b * c;
    this.spu = function(d, c, det) { return function(x, y) { return (d * x - c * y) / det; }; }(d, c, det);
    this.spv = function(a, b, det) { return function(x, y) { return (a * y - b * x) / det; }; }(a, b, det);
}

Map.prototype.sizeS = function(w, h) {
    if (w != this.divw || h != this.divh) {
        this.div.style.width = makeSize(w);
        this.div.style.height = makeSize(h);
        this.divw = w;
        this.divh = h;
        this.divcx = Math.round(w / 2);
        this.divcy = Math.round(h / 2 + this.rd * 2);
    }
}

Map.prototype.centerS = function(x, y) {
    if (x != this.centerx || y != this.centery) {
        this.centerx = x;
        this.centery = y;
        this.centerc = true;
    }
}

Map.prototype.centerR = function() {
    if (this.centerc) {
        delete this.centerc;
        var cx = this.divcx - this.spx(this.centerx, this.centery);
        var cy = this.divcy - this.spy(this.centerx, this.centery);
        if (this.efmsl) {
            if (this.efmsl.cx == undefined || this.efmsl.cy == undefined) {
                this.efmsl.cx = cx;
                this.efmsl.cy = cy;
            } else {
                this.efmsl.nx = cx;
                this.efmsl.ny = cy;
                return;
            }
        }
        this.et.style.left = cx + "px";
        this.et.style.top = cy + "px";
        this.eo.style.left = cx + "px";
        this.eo.style.top = cy + "px";
        this.ee.style.left = cx + "px";
        this.ee.style.top = cy + "px";
    }
}

Map.prototype.layout = function() {
    if (this.efsl || this.effd || this.efmsl || this.efhl)
        this.efT(2);
    if (this.efmsl)
        this.efmsl = {};
    this.centerc = true;
    this.centerR();
}

Map.prototype.vaS = function(va) {
    if (this.va != va) {
        this.va = (va + 11) % 12 + 1;
        this.spfS();

        this.div.removeChild(this.et);
        for (var i = 0, k = 1, n = this.tl.length; i < n; i++) {
            var t = this.tl[i];
            t.px = this.spx(t.x, t.y);
            t.py = this.spy(t.x, t.y);
            var ed = this.Sg(t.st).i(this.va - t.va).d(t.px, t.py);
            if (t.ed != ed) {
                this.et.removeChild(t.ed);
                t.ed = ed;
            }

            if (i >= k << 1)
                k <<= 1;
            for (var l = -1, j = k; j; j >>= 1)
                if (l + j < i && t.py >= this.tl[l + j].py)
                    l += j;
            l += 1;
            if (l < i) {
                this.et.insertBefore(ed, this.tl[l].ed);
                this.tl.splice(i, 1);
                this.tl.splice(l, 0, t);
            } else
                this.et.insertBefore(ed, i > 0 ? this.tl[i - 1].ed.nextSibling : this.et.firstChild);
        }
        this.et.style.display = "none";
        this.div.insertBefore(this.et, this.eo);

        this.div.removeChild(this.eo);
        for (var j = 0, k = 1, n = this.ol.length; j < n; j++) {
            var o = this.ol[j];
            o.px = this.spx(o.x, o.y);
            o.py = this.spy(o.x, o.y);
            var i = this.Sg(o.st).i(this.va - o.va);
            var ei = i.i(o.px, o.py);
            if (o.ei != ei) {
                this.eo.removeChild(o.ei);
                o.ei = ei;
                o.em = i.m();
            }

            if (j >= k << 1)
                k <<= 1;
            for (var l = -1, m = k; m; m >>= 1)
                if (l + m < j && o.py >= this.ol[l + m].py)
                    l += m;
            l += 1;
            if (l < j) {
                this.eo.insertBefore(ei, this.ol[l].ei);
                this.ol.splice(j, 1);
                this.ol.splice(l, 0, o);
            } else
                this.eo.insertBefore(ei, j > 0 ? this.ol[j - 1].ei.nextSibling : this.eo.firstChild);
        }
        this.eo.style.display = "none";
        this.div.insertBefore(this.eo, this.et.nextSibling);

        this.layout();

        this.eo.style.display = this.et.style.display = "";
    }
}

Map.prototype.Ig = function(s) {
    var i = this.il[s];
    if (!i)
        return this.il[s] = new this.I(s);
    return i;
}

Map.prototype.Ia = function(l) {
    var is = l[0];
    var i = this.Ig(is);
    i.cx = l[1];
    i.cy = l[2];
    i.w = l[3];
    i.h = l[4];
    return i;
}

Map.prototype.Sg = function(t) {
    var s = this.sl[t];
    if (!s)
        return this.sl[t] = new this.S(t);
    return s;
}

Map.prototype.Sa = function() {
    var st = arguments[0];
    var s = this.Sg(st);
    for (var i = 1, n = arguments.length; i < n; i++)
        s.il.push(this.Ia(arguments[i]));
}

Map.prototype.Tg = function(x, y) {
    var r = this.tc[y];
    if (!r)
        this.tc[y] = r = [];

    var t = r[x];
    if (!t) {
        t = r[x] = new this.T(x, y);
        t.x = x;
        t.y = y;
        t.px = this.spx(x, y);
        t.py = this.spy(x, y);
    }

    return t;
}

Map.prototype.Ta = function(x, y, st, va) {
    var t = this.Tg(x, y);
    if (t.st != st || t.va != va) {
        t.st = st;
        t.va = va;
        var ed = this.Sg(st).i(this.va - t.va).d(t.px, t.py);
        if (t.ed)
            this.et.replaceChild(ed, t.ed);
        else {
            for (var j = 1, k = this.tl.length; j << 1 <= k; j <<= 1);
            for (var l = -1; j; j >>= 1)
                if (l + j < k && t.py >= this.tl[l + j].py)
                    l += j;
            l += 1;
            if (l < k)
                this.et.insertBefore(ed, this.tl[l].ed);
            else
                this.et.appendChild(ed);
            this.tl.splice(l, 0, t);
        }
        t.ed = ed;
    }
}

Map.prototype.Td = function(x, y) {
    var r = this.tc[y];
    if (r) {
        var t = r[x];
        delete r[x];
        if (t) {
            if (t.ed)
                this.et.removeChild(t.ed)
            var l = this.tl.indexOf(t);
            this.tl.splice(l, 1);
        }
    }
}

Map.prototype.Tda = function() {
    removeChildren(this.et);
    this.tc = [];
    this.tl = [];
    removeChildren(this.eo);
    this.ot = [];
    this.ol = [];
    removeChildren(this.ee);
    if (this.efmsl)
        this.efmsl = {};
}

Map.prototype.Og = function(t) {
    var o = this.ot[t];
    if (!o)
        return this.ot[t] = new this.O(t);
    return o;
}

Map.prototype.Oa = function(t, x, y, st, va, name) {
    var o = this.Og(t);
    var cp = o.x != x || o.y != y;
    o.x = x;
    o.y = y;
    var ci = o.st != st || o.va != va;
    o.st = st;
    o.va = va;
    o.name = name;

    if (o.t in this.lo)
        delete this.lo[o.t];

    if (!o.ei) {
        o.px = this.spx(o.x, o.y);
        o.py = this.spy(o.x, o.y);
        var i = this.Sg(o.st).i(this.va - o.va);
        o.ei = i.i(o.px, o.py);
        o.em = i.m();

        o.i(this.ol, this.eo);
        if (this.effd) {
            o.ei.style.opacity = "0";
            var j = this.effd.indexOf(o);
            if (j < 0)
                this.effd.push(o);
            o.efoc = 0;
            o.efot = 1;
        }
    } else {
        if (this.efsl) {
            var j = this.efsl.indexOf(o);
            if (j < 0)
                this.efsl.push(o);
            if (ci) {
                var ei = o.ei;
                var i = this.Sg(o.st).i(this.va - o.va);
                o.ei = i.i(o.px, o.py);
                o.em = i.m();
                this.eo.replaceChild(o.ei, ei);
            }
            o.efpx = this.spx(o.x, o.y);
            o.efpy = this.spy(o.x, o.y);
            return;
        }

        if (cp) {
            var pyo = o.py;
            o.px = this.spx(o.x, o.y);
            o.py = this.spy(o.x, o.y);
            if (!ci) {
                o.ei.style.left = o.px + "px";
                o.ei.style.top = o.py + "px";
            }
        }

        if (ci) {
            var ei = o.ei;
            var i = this.Sg(o.st).i(this.va - o.va);
            o.ei = i.i(o.px, o.py);
            o.em = i.m();
            this.eo.replaceChild(o.ei, ei);
            if (!cp)
                return;
        }

        o.m(pyo, this.ol, this.eo);
    }
}

Map.prototype.Od = function(t) {
    var o = this.Og(t);
    delete this.ot[o.t];

    if (o.t in this.clo) {
        this.lo[o.t] = true;
        client.click('+' + o.t);
    }

    if (this.effd && o.ei) {
        var j = this.effd.indexOf(o);
        if (j < 0)
            this.effd.push(o);
        o.efoc = 1;
        o.efot = 0;
        return;
    }

    o.d(this.ol, this.eo);
}

Map.prototype.Ea = function(t, k, c) {
    var o = this.ot[t];
    var ei = o && o.ei;
    var em = emSize();
    var spr = em * (k ? .2 : .5);
    if (ei) {
        var py = (o.efpy != undefined ? o.efpy : o.py) -
            1.5 * em + Math.round((Math.random() - .5) * spr);
        var oi = this.Sg(o.st).i(this.va - o.va);
        if (oi)
            py -= oi.cy;
        var e = createElement("div");
        e.style.position = "absolute";
        e.style.left = (o.efpx != undefined ? o.efpx : o.px)  +
            Math.round((Math.random() - .5) * 2 * spr) + "px";
        e.style.top = py + "px";
        if (k > 1)
            e.style.display = "none";
        var className = [ "effect", "attack", "defense", "hit" ][k];
        for (var i = 0; i < 5; i++) {
            var et = createElement("div");
            et.className = className;
            et.style.position = "absolute";
            et.style.left = i == 0 ? "1px" : i == 2 ? "-1px" : "0px";
            et.style.top = i == 1 ? "1px" : i == 3 ? "-1px" : "0px";
            if (i != 4)
                et.style.color = "black";
            et.style.width = "15em";
            et.style.marginLeft = "-7.5em";
            et.style.textAlign = "center";
            et.style.cursor = "default";
            et.appendChild(document.createTextNode(c));
            e.appendChild(et);
        }
        e.appendChild(et);
        this.ee.appendChild(e);
        setTimeout(function(e, d, py, n) { var f = function() {
            if (n == 2) e.style.display = "";
            if (n > 0) e.style.top = (py -= d) + "px";
            if (n < -10) e.style.opacity = (n + 20) / 10;
            if (n-- > -20) setTimeout(f, 50); else if (e.parentNode) e.parentNode.removeChild(e);
        }; return f; }(e, k ? 1 : 2, py, k ? 5 : 10), 50);
    }
}

Map.prototype.hl = function() {
    if (this.efhl) {
        var efhl = this.efhl;
        this.efhl = [];
        for (var i = 1; i < arguments.length; i += 2) {
            var t = this.tc[arguments[i]] && this.tc[arguments[i]][arguments[i - 1]];
            if (t) {
                this.efhl.push(t);
                var j = this.efhl.indexOf(t);
                if (j >= 0)
                    efhl.splice(j, 1);
            }
        }
        for (var i = 0; i < efhl.length; i++)
            if (efhl[i].ed)
                efhl[i].ed.style.opacity = "";
    }
}

Map.prototype.evct = function(ev) {
    var sx = ev.clientX - this.et.offsetLeft;
    var sy = ev.clientY - this.et.offsetTop;
    for (var e = this.div; e.offsetParent; e = e.offsetParent) {
        sx -= e.offsetLeft;
        sy -= e.offsetTop;
    }

    var u = this.spu(sx, sy);
    var v = this.spv(sx, sy);

    var a = Math.floor(v - u);
    var b = Math.floor(2 * u + v);
    var c = Math.floor(2 * v + u);

    var x = Math.floor((b - a + 1) / 3);
    var y = Math.floor((c + a + 2) / 3);
    return { x: x, y: y };
}

Map.prototype.evot = function(ev) {
    var sx = ev.clientX - this.eo.offsetLeft;
    var sy = ev.clientY - this.eo.offsetTop;
    for (var e = this.div; e.offsetParent; e = e.offsetParent) {
        sx -= e.offsetLeft;
        sy -= e.offsetTop;
    }

    var r = [];
    for (var i = this.ol.length - 1; i >= 0; i--) {
        var o = this.ol[i];
        if (o.ei && sx >= o.ei.offsetLeft && sx < o.ei.offsetLeft + o.ei.offsetWidth && sy >= o.ei.offsetTop && sy < o.ei.offsetTop + o.ei.offsetHeight)
            if (!o.em || !o.em[sy - o.ei.offsetTop] || !o.em[sy - o.ei.offsetTop][sx - o.ei.offsetLeft] || o.em[sy - o.ei.offsetTop][sx - o.ei.offsetLeft] == ".")
                r.push(o);
    }
    return r;
}

Map.prototype.evc = function(ev) {
    var co = this.evot(ev);
    for (var i = 0; i < co.length; i++)
        if (chat.c.co(co[i]))
            return;

    var ct = this.evct(ev);
    if (chat.c.ct(ct))
        return;

    client.click("*" + ct.x + "," + ct.y);
}

Map.prototype.evk = function(ev) {
    var key = ev.keyCode || ev.which;
    if (ev.ctrlKey) {
        var r = key == 37 ? 1 : key == 39 ? -1 : 0;
        if (r) {
            this.vaS(this.va + r);
            stopEventPropagation(ev);
            client.click("[" + this.va);
        }
    }
}

Map.prototype.epset = function(x, y, text) {
    if (text) {
        this.ep.style.visibility = "";
        removeChildren(this.ep);
        this.ep.appendChild(document.createTextNode(text));
        this.ep.style.left = x + "px";
        this.ep.style.top = y + "px";
    } else
        this.ep.style.visibility = "hidden";
}

Map.prototype.evm = function(ev) {
    var ct = this.evct(ev);
    //this.epset(ev.clientX + 5, ev.clientY + 5, "(" + mc.x + "; " + mc.y + ")");
}

Map.prototype.pre = function() {
    if (this.efsl || this.effd || this.efmsl || this.efhl)
        this.efT(2);

    this.clo = chat.lo();
}

Map.prototype.post = function() {
    var llo = this.lo;
    this.lo = {};
    for (var i in llo)
        if (i in this.clo)
            this.lo[i] = true;
        else
            client.click('-' + i);
    delete this.clo;

    this.centerR();
    if (this.efsl || this.effd || this.efmsl || this.efhl)
        this.efT(1);
}


/* initialization */

map = new Map;

