﻿/* Polaroid Images */
var PolaroidImages = new function () {

    this.Create = function (oContainer, sBackgroundURL, iBackgroundWidth, iBackgroundHeight, iImageOffsetLeft, iImageOffsetTop,
            iImageWidth, iImageHeight, nMaxDegreesRotation, iOverlap, bAnimate) {

        if (!Raphael) return; //bomb out and leave images as is if there are any problems


        oContainer = f.SafeObject(oContainer);

        //get image sources
        var aImageSources = new Array();
        var aImages = f.GetElementsByClassName('img', 'polaroid', oContainer);
        for (var i = 0; i < aImages.length; i++) aImageSources.push(aImages[i].src);

        //remove all the children of the container div
        while (oContainer.hasChildNodes()) oContainer.removeChild(oContainer.firstChild);

        //find the rotation centre points
        var iImageRotationPointX = Math.floor(iImageWidth / 2.0);
        var iImageRotationPointY = Math.floor(iImageHeight / 2.0);
        var iBackgroundRotationPointX = iImageOffsetLeft + iImageRotationPointX;
        var iBackgroundRotationPointY = iImageOffsetTop + iImageRotationPointY;

        //work out the margins and padding
        var nMaxRadiansRotation = nMaxDegreesRotation * ((2.0 * Math.PI) / 360.0);
        var nMaxHeightAboveCentre = iBackgroundRotationPointX * Math.sin(nMaxRadiansRotation) + iBackgroundRotationPointY * Math.cos(nMaxRadiansRotation);
        var nMaxHeightBelowCentre = (iBackgroundWidth - iBackgroundRotationPointX) * Math.sin(nMaxRadiansRotation) + (iBackgroundHeight - iBackgroundRotationPointY) * Math.cos(nMaxRadiansRotation);
        var iMaxAdditionalHeightAbove = Math.ceil(nMaxHeightAboveCentre - iBackgroundRotationPointY);
        var iMaxAdditionalHeightBelow = Math.ceil(nMaxHeightBelowCentre - (iBackgroundHeight - iBackgroundRotationPointY));

        var iImageMarginTop = Math.floor(iMaxAdditionalHeightAbove - iOverlap / 2.0);
        var iImageMarginBottom = Math.floor(iMaxAdditionalHeightBelow - iOverlap / 2.0);

        var iTopPadding = aImageSources.length != 0 ? iMaxAdditionalHeightAbove : 0;
        var iBottomPadding = aImageSources.length != 0 ? iMaxAdditionalHeightBelow : 0;

        //now set up the canvas
        var oCanvasPosition = e.GetPosition(oContainer);
        var iCanvasWidth = oCanvasPosition.Width;
        var iCanvasHeight = iTopPadding + iBottomPadding + aImageSources.length * iBackgroundHeight + (aImageSources.length != 0 ? (aImageSources.length - 1) * (iImageMarginTop + iImageMarginBottom) : 0);

        var oRaphael = Raphael(oContainer, iCanvasWidth, iCanvasHeight);

        //calculate left positions
        var iBackgroundLeft = Math.floor(iCanvasWidth / 2.0 - iBackgroundWidth / 2.0);
        var iImageLeft = iBackgroundLeft + iImageOffsetLeft;

        //add the images and rotate
        var iCurrentDirectionMultiplier = Math.floor(Math.random() * 2) == 1 ? 1 : -1;
        for (var i = 0; i < aImageSources.length; i++) {
            var iBackgoundTop = iTopPadding + i * (iImageMarginTop + iBackgroundHeight + iImageMarginBottom);
            var iImageTop = iBackgoundTop + iImageOffsetTop;

            var nRotateDegrees = Math.sqrt(Math.random()) * nMaxDegreesRotation * iCurrentDirectionMultiplier;
            //nRotateDegrees = 1 * nMaxDegreesRotation * iCurrentDirectionMultiplier; //for testing

            var oBackground = oRaphael.image(sBackgroundURL, iBackgroundLeft, iBackgoundTop, iBackgroundWidth, iBackgroundHeight);
            var oImage = oRaphael.image(aImageSources[i], iImageLeft, iImageTop, iImageWidth, iImageHeight);
            oBackground.rotate(nRotateDegrees, iBackgroundLeft + iBackgroundRotationPointX, iBackgoundTop + iBackgroundRotationPointY);
            oImage.rotate(nRotateDegrees, iImageLeft + iImageRotationPointX, iImageTop + iImageRotationPointY);

            if (bAnimate) {
                //I'm calling into a function here to make use of javascript closures
                PolaroidImages.AttachAnimationEvents(oImage, oBackground, nRotateDegrees);
            }

            iCurrentDirectionMultiplier *= -1;
        }

    }


    this.AttachAnimationEvents = function (oImage, oBackground, nRotationAngle) {

        //Rotation animations frequently suffer from a flaw when they try and pass the zero point, so that's why I'm dividing
        //nRotationAngle by 3. The animation runs smoothly. ;)
        var oRotate = function (event) { PolaroidImages.Rotate(oImage, oBackground, (nRotationAngle / 3.0), 300); };
        var oRotateBack = function (event) { setTimeout(function () { PolaroidImages.Rotate(oImage, oBackground, nRotationAngle, 500); }, 200); };

        oImage.mouseover(oRotate);
        oImage.mouseout(oRotateBack);

    }

    this.Rotate = function (oImage, oBackground, sRotationAngle, iTime) {
        var aRotation = oImage.rotate().split(' ');
        var aBgRotation = oBackground.rotate().split(' ');

        oImage.animate({ rotation: new Array(sRotationAngle, aRotation[1], aRotation[2]).join(' ') }, iTime);
        oBackground.animateWith(oImage, { rotation: new Array(sRotationAngle, aBgRotation[1], aBgRotation[2]).join(' ') }, iTime);
    }

}
