/*
  Copyright 2008 Mark Williams (mark_st@myosotissp.com)

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/

/*
  Bug fix for prototype.
  On IE, Element.getOffsetParent will sometimes find its way to the document 
  node, and then crash (because document nodes have no style).
*/
if (Element.getOffsetParent &&
    !Element.getOffsetParent.toString().match(/'HTML'/))
{
    Element.getOffsetParent = function(element) {
        element = $(element);
        var op = element.offsetParent;
        if (op && op != document.documentElement) return $(op);

        while (element.tagName.toUpperCase() != 'HTML' && (element = element.parentNode))  
            if (Element.getStyle(element, 'position') != 'static')
                return $(element);

        return $(document.body);
    }
}

Window.prototype._makeRoundShim = function(id, opts)
{
    var div = document.createElement('div');
    div.id = id;
    div.style.position = "absolute";
    div.style.display = "none";
    div.style.border = "0px";

    var rad,tl,tr,bl,br;

    function makeShim(x,y)
    {
        /*
          The idea here is to create an iframe thats inset
          from "div" (above) by top, left, bottom, right.
          
          The obvious way would be to create an absolutely
          positioned iframe, and set the top, left, bottom and
          right fields. But that would be too easy :-)

          Firefox ignores bottom and right, and instead leaves
          height at 100px, and width at 300px (the defaults for
          an iframe). Im not 100% sure if this is a bug or a
          feature.

          So the fix is to create a div, positioned as described,
          and put the iframe inside it, with width=heigh=100%.

          But IE has problems. In IE7, the div ends up correctly
          positioned, but the "100%" on the height doesnt work,
          because the height of the parent element (the div) isnt
          set explicitly (a known bug).
          Worse, if you set both top and bottom, or both left and right
          IE6 ignores the second.

          So for IE, we position the div relative to the bottom right,
          but set its height/width to 100%, and also set overflow hidden.
          Then we offset the iframe from the top left. Now the intersection
          of the div and the iframe is exactly the region we're after.

          Finally, this approach doesnt work for FF, because the
          "overflow hidden" doesnt prevent the iframe from punching through
          the "earth"!

          So we browser sniff.

          Perhaps a better way, would have been to produce a 3x3 table,
          and do separate rounded corners in each corner :-)
        */
        var shimd = document.createElement('div');
        var top = (tl || tr ? y : 0);
        var bottom = (bl || br ? y : 0);
        var left = (tl || bl ? x : 0);
        var right = (tr || br ? x : 0);
        shimd.style.position = "absolute";
        shimd.style.overflow = "hidden";
        shimd.style.border = "0px";
        shimd.style.right = right+"px";
        shimd.style.bottom = bottom+"px";
        if (Prototype.Browser.IE) {
            shimd.style.height = "100%";
            shimd.style.width = "100%";
        } else {
            shimd.style.top = top+"px";
            shimd.style.left = left+"px";
        }

        var shim = document.createElement('iframe');

        shim.frameborder = 0;
        shim.scrolling = "no";
        shim.style.border = "0px";
        shim.style.height = shim.style.width = "100%";
        if (Prototype.Browser.IE) {
            shim.style.position = "absolute";
            shim.style.top = (top+bottom)+"px";
            shim.style.left = (left+right)+"px";
        }
        //shim.style.right = (left+right)+"px";

        shimd.appendChild(shim);
        div.appendChild(shimd);
        return shimd;
    }

    function makeCorner(rad, p1, p2)
    {
        var shim = document.createElement('iframe');

        shim.style.position = "absolute";
        shim.frameborder = 0;
        shim.scrolling = "no";
        shim.style.border = "0px";
        shim.style.height = shim.style.width = rad + "px";
        shim.style[p1] = shim.style[p2] = "0px";
        div.appendChild(shim);
    }

    if (opts && opts.radius) {
        rad = parseInt(Math.round(opts.radius));
        tl = tr = bl = br = true;
        if ("top" in opts) { tl = tr = opts.top }
        if ("left" in opts) { tl = bl = opts.left }
        if ("bottom" in opts) { bl = br = opts.bottom }
        if ("right" in opts) { tr = br = opts.right }
        if ("topLeft" in opts) tl = opts.topLeft;
        if ("topRight" in opts) tr = opts.topRight;
        if ("bottomLeft" in opts) bl = opts.bottomLeft;
        if ("bottomRight" in opts) br = opts.bottomRight;

        var py = rad, px = 0;
        for (var x = 1; x <= rad; x++) {
            var y = parseInt(Math.round(Math.sqrt(rad*rad - x*x)));
            if (y != py) {
                makeShim(rad-x+1,rad-py);
                py = y;
            }
        }
        makeShim(0,rad);

        // The above has rounded the required corners.
        // It may have also rounded unwanted corners.
        // In that case (rare) add square shims in
        // the appropriate corners.
        if (tl && br) {
            if (!tr) {
                makeCorner(rad, "top", "right");
            }
            if (!bl) {
                makeCorner(rad, "bottom", "left");
            }
        }
        if (tr && bl) {
            if (!tl) {
                makeCorner(rad, "top", "left");
            }
            if (!br) {
                makeCorner(rad, "bottom", "right");
            }
        }
       
    } else {
        makeShim(0,0);
    }
    return div;
}

/*
  Fixes for PWC to make ishims work correctly
*/

Window.prototype._checkIEOverlapping = function()
{
    if(!this.iefix && (this.element.getStyle('position')=='absolute')) {
        var opts = this.options.rc_opts || {
            "radius":8,
            "bottom":false
        };
        
        this.iefix = this._makeRoundShim(this.element.id+'_iefix', opts);
        this.element.parentNode.insertBefore(this.iefix, this.element);
    }
    if(this.iefix) 
        setTimeout(this._fixIEOverlapping.bind(this), 50);
};

Window.prototype._fixIEOverlapping = function() {
    if (!this.iefix) return;

    Element.clonePosition(this.iefix, this.currentDrag || this.element);
    this.iefix.style.zIndex = this.element.style.zIndex;
    this.iefix.show();
};

Window._saveWindowFuncs = {};

["minimize", "maximize", "setSize"].each(function(f) {
        Window._saveWindowFuncs[f] = Window.prototype[f];
        Window.prototype[f] = function() {
            Window._saveWindowFuncs[f].apply(this, arguments);
            if (this.iefix) this._fixIEOverlapping();
        };
    });

Window._saveWindowFuncs.setCookie = Window.prototype.setCookie;

Window.prototype.setCookie = function(name, expires, path, domain, secure)
{
    if (arguments.length < 2) {
        expires = new Date();
        expires.setTime(expires.getTime()+(365*24*60*60*1000));
    }

    Window._saveWindowFuncs.setCookie.apply(this, [name, expires, path, domain, secure]);
}

Window.prototype._notify = function(eventName) {
    if (this.options[eventName])
      this.options[eventName](this);

    Windows.notify(eventName, this);
};

if (Prototype.Browser.IE) {
    var f = Window.prototype._getWindowBorderSize.toString();
    f = f.replace(/\(Prototype.Browser.IE\)/, "(!this.heightS&&!this.heightN)");
    // it would be nicer to do f=eval(f)
    // but that doesnt work in IE.
    eval("f="+f);
    Window.prototype._getWindowBorderSize = f;
}

function setupIShimObserver() {
    if (document.body.setCapture) {
        /*
          This is needed on ie to ensure that
          window dragging works correctly
        */

        var ie_start = function(eventName, win) {
            document.body.setCapture();
        };

        var ie_end = function(eventName, win) {
            document.body.releaseCapture();
        };

        var fixupObserver = {
            "onStartMove" : ie_start,
            "onStartResize" : ie_start,
            "onEndResize" : ie_end,
            "onEndMove" : ie_end
        }

        Windows.addObserver(fixupObserver);
    }
}

(function() {
    var disable = WindowUtilities.disableScreen;
    var enable = WindowUtilities.enableScreen;
    var screenOverlay = null;
    var nav_vis;

    var null_handler = function(event) {
        event.preventDefault();
        event.stopPropagation();
    };

    WindowUtilities.disableScreen = function(className, overlayId, overlayOpacity, contentId, parent) {
        disable.apply(this, arguments);
        if (className == '__invisible__') return;

        var ge = WindowUtilities.ge;
        if (ge) {
            if (!screenOverlay) {
                screenOverlay = ge.createScreenOverlay('');

                screenOverlay.getScreenXY().set(0, ge.UNITS_PIXELS,
                                                0, ge.UNITS_PIXELS);
                screenOverlay.getOverlayXY().set(0, ge.UNITS_PIXELS,
                                                 0, ge.UNITS_PIXELS);

                screenOverlay.getSize().set(1, ge.UNITS_FRACTION,
                                            1, ge.UNITS_FRACTION);

                opacity = parseInt(overlayOpacity * 255).toString(16);
                if (opacity.length == 1) opacity = '0' + opacity;

                screenOverlay.getColor().set(opacity + "808080");

                ge.getFeatures().appendChild(screenOverlay);
            }

            google.earth.addEventListener(ge.getWindow(),"click", null_handler, true);
            google.earth.addEventListener(ge.getWindow(),"dblclick", null_handler, true);
            google.earth.addEventListener(ge.getWindow(),"mouseover", null_handler, true);
            google.earth.addEventListener(ge.getWindow(),"mousedown", null_handler, true);
            google.earth.addEventListener(ge.getWindow(),"mouseup", null_handler, true);
            google.earth.addEventListener(ge.getWindow(),"mouseout", null_handler, true);
            google.earth.addEventListener(ge.getWindow(),"mousemove", null_handler, true);

            nav_vis = ge.getNavigationControl().getVisibility();
            ge.getNavigationControl().setVisibility(ge.VISIBILITY_HIDE);
        }
    };

    WindowUtilities.enableScreen = function(id) {
        enable.apply(this, arguments);
        if (id == '__invisible__') return;
        var ge = WindowUtilities.ge;
        if (ge) {
            if (screenOverlay) {
                ge.getFeatures().removeChild(screenOverlay);
                screenOverlay = null;
            }

            google.earth.removeEventListener(ge.getWindow(),"click", null_handler, true);
            google.earth.removeEventListener(ge.getWindow(),"dblclick", null_handler, true);
            google.earth.removeEventListener(ge.getWindow(),"mouseover", null_handler, true);
            google.earth.removeEventListener(ge.getWindow(),"mousedown", null_handler, true);
            google.earth.removeEventListener(ge.getWindow(),"mouseup", null_handler, true);
            google.earth.removeEventListener(ge.getWindow(),"mouseout", null_handler, true);
            google.earth.removeEventListener(ge.getWindow(),"mousemove", null_handler, true);

            ge.getNavigationControl().setVisibility(nav_vis);
        }
    }

})();
