var isSvg = !svg2vml.prototype.vml_capable;

var renderWidth = 600;
var renderHeight = 400;

var renderSF = 1;

var svgNS = "http://www.w3.org/2000/svg";
var starCanvas = null;
var boxCanvas = null;
var textCanvas = null;

function createSvgDoc()
{
    var container = document.getElementById("splashContent");
    var mySvg = document.createElementNS(svgNS, "svg");

    renderSF = Math.min( renderWidth/600, renderHeight/400 );
    container.appendChild(mySvg);
    mySvg.setAttribute("version", "1.1");
    mySvg.setAttribute("width", renderWidth);
    mySvg.setAttribute("height", renderHeight);
    mySvg.onclick = detonateBox;

    var myG = document.createElementNS( svgNS, "g");
    myG.setAttribute("id", "starCanvas");
    starCanvas = myG;
    mySvg.appendChild(myG);

    myG = document.createElementNS( svgNS, "g");
    myG.setAttribute("id", "boxCanvas");
    boxCanvas = myG;
    mySvg.appendChild(myG);

    myG = document.createElementNS( svgNS, "g");
    myG.setAttribute("id", "textCanvas");
    textCanvas = myG;
    mySvg.appendChild(myG);
}
    
/////////////////////////////////////////
//Simple starfield:
var stars = [];
var starBoundsX;
var starBoundsY;
var starCentreX;
var starCentreY;
var starSpeed;
var starDiscardRange;

function initStarParams()
{
    starBoundsX = renderWidth;
    starBoundsY = renderHeight;
    starCentreX = starBoundsX/2;
    starCentreY = starBoundsY/2;

    starSpeed = 0.1*renderSF;
    starDiscardRange = 200*200*renderSF*renderSF;
}

function initialiseStar( _star, _newStar )
{
    var randX = ((Math.random()*100) - 50)*renderSF;
    var randY = ((Math.random()*100) - 50)*renderSF;
    if ( Math.abs(randY) < 10 )
    {
        randY = 10;
    }
    _star.setAttribute( 'cx', starCentreX + randX );
    _star.setAttribute( 'cy', starCentreY + randY );
    if ( isSvg )
    {
        _star.setAttribute( 'r', 2*renderSF ); //Svg resizes sensibly
        _star.setAttribute( 'fill','rgb(255,255,255)' );
        _star.setAttribute( 'opacity', 0.5 );
    }
    else if (_newStar)
    {
        _star.setAttribute( 'r', (2+2*Math.random())*renderSF ); //VML doesn't, set some defaults
        _star.setAttribute( 'fill','rgb(235,235,255)' );
    }
    _star.setAttribute( 'stroke-width', 0 );
    _star.radius = 2.0;
}
function spawnStar()
{
    var canvas = starCanvas;
    var star = document.createElementNS(svgNS, 'circle');
    initialiseStar( star, true );                        
    canvas.appendChild( star );
    stars[ stars.length ] = star;
}
function animateStars()
{
    //TODO: Rewrite in a non frame-rate dependent way?
    var i;
    for (i=0;i<stars.length;i++)
    {
        var star = stars[i];
        var x = parseInt(star.getAttribute('cx'));
        var y = parseInt(star.getAttribute('cy'));
        
        var dx = parseInt((x-starCentreX)*starSpeed);
        var dy = parseInt((y-starCentreY)*starSpeed);

        //Make sure we don't have crazy stars:
        if ( dx == 0 && dy == 0 )
        {
            dx = Math.random()*10 - 5;
            dy = Math.random()*10 - 5;
        }

        x += dx;
        y += dy;
        star.radius += starSpeed;
     
        var dstSqu = (x-starCentreX)*(x-starCentreX) + (y-starCentreY)*(y-starCentreY);
   
        if ( dstSqu > starDiscardRange )
        {
            initialiseStar(star);                    
        }
        else
        {
            star.setAttribute( 'cx', x );
            star.setAttribute( 'cy', y );
            if ( isSvg )
            {
                star.setAttribute( 'r', parseInt(star.radius) );
            }
        }
    }
}
    
////////////////////////////////////////
//Box stuff
function Vector3(x,y,z)
{
    this.x = x;
    this.y = y;
    this.z = z;
}
function v3_dot( _v1, _v2 )
{
    return _v1.x*_v2.x + _v1.y*_v2.y + _v1.z*_v2.z;
}
function v3_scale( _v, _sf )
{
    return new Vector3(_v.x*_sf, _v.y*_sf, _v.z*_sf);
}
function v3_add( _v1, _v2 )
{
    return new Vector3( _v1.x + _v2.x, _v1.y + _v2.y, _v1.z + _v2.z );
}
function v3_sub( _v1, _v2 )
{
    return new Vector3( _v1.x - _v2.x, _v1.y - _v2.y, _v1.z - _v2.z );
}
function v3_cross( _v1, _v2 )
{
    return new Vector3( _v1.y*_v2.z - _v2.y*_v1.z, _v1.z*_v2.x - _v2.z*_v1.x, _v1.x*_v2.y - _v2.x*_v1.y );
}
function v3_len( _v )
{
    return Math.sqrt(_v.x*_v.x + _v.y*_v.y + _v.z*_v.z);
}
function v3_normalise( _v )
{
    return v3_scale( _v, 1.0/v3_len(_v) );
}
function v3_rotateAround( _v, _norm, _cosAngle, _sinAngle )
{
    //TODO: Optimise, if necessary:
    var a = v3_scale( _norm, v3_dot(_v, _norm) );
    var n1 = v3_sub( _v, a );
    var n2 = v3_cross( _norm, n1 );
    return v3_add( v3_add( a, v3_scale(n1,_cosAngle) ), v3_scale(n2,_sinAngle) );
}


var boxDefaultSize = 60;
var boxPts = [];
var boxConnectivity = [ 0,1, 1,2, 2,3, 3,0, 
                        4,5, 5,6, 6,7, 7,4,
                        0,4, 1,5, 2,6, 3,7 ];
var boxPtElements = [];
var boxEdgeElements = [];
var boxRotAxis = new Vector3(0,1,0);
var boxDetonation = false;
var boxDetonationTime = 0;
var boxSpawnDistance = 0;
                
//Project into view:
function projectBoxX( _pt )
{
    return _pt.x*renderSF*240/(_pt.z+300+boxSpawnDistance) + starCentreX;
}
function projectBoxY( _pt )
{
    return _pt.y*renderSF*240/(_pt.z+300+boxSpawnDistance) + starCentreY;
}

function spawnBox()
{
    boxSpawnDistance = 20000;
    boxDetonation = false;
    var boxSize = boxDefaultSize;
    boxPts = [  new Vector3(-boxSize,-boxSize,-boxSize), new Vector3(boxSize,-boxSize,-boxSize), new Vector3(boxSize,boxSize,-boxSize), new Vector3(-boxSize,boxSize,-boxSize), 
                new Vector3(-boxSize,-boxSize,boxSize), new Vector3(boxSize,-boxSize,boxSize), new Vector3(boxSize,boxSize,boxSize), new Vector3(-boxSize,boxSize,boxSize) ];

    var canvas = boxCanvas;
    var i;
    for (i=0;i<boxConnectivity.length;i+=2)
    {
        var boxEdge = document.createElementNS(svgNS, 'line');
        boxEdge.setAttribute( 'stroke','rgb(230,230,255)' );
        boxEdge.setAttribute( 'stroke-width', parseInt(3*renderSF) );

        boxEdgeElements[ i/2 ] = boxEdge;
        canvas.appendChild( boxEdge );    
    }
    for ( i=0;i<boxPts.length;i++)
    {
        var boxPt = document.createElementNS(svgNS, 'circle');
        boxPt.setAttribute( 'r', parseInt(4*renderSF));
        boxPt.setAttribute( 'stroke-width', '0' );
        boxPt.setAttribute( 'fill','rgb(255,255,255)' );     
        boxPtElements[ i ] = boxPt;
        canvas.appendChild( boxPt );
    }

    animateBox();
}       
function animateBox()
{
    //TODO: Rewrite in a non frame-rate dependent way?
    if ( boxDetonation )
    {
        boxDetonationTime--;

        //Inflate points:
        var i;
        for ( i=0;i<boxPtElements.length;i++)
        {
            //Similar to stars:
            var boxPt = boxPtElements[i];
            if ( !boxPt ) continue;
            
            var opacity = boxPt.getAttribute('opacity');
            if ( !opacity )
            {
                opacity = 1.0;
            }
            if (opacity<0.1 || boxDetonationTime<0)
            {
                boxPt.parentNode.removeChild( boxPt );
                boxPtElements[i] = null;
                continue;
            }
            var x = parseInt(boxPt.getAttribute('cx'));
            var y = parseInt(boxPt.getAttribute('cy'));
            var r = parseFloat(boxPt.getAttribute('r'));
            
            x += (x-starCentreX)*starSpeed;
            y += (y-starCentreY)*starSpeed;
            
            boxPt.setAttribute( 'cx', x );
            boxPt.setAttribute( 'cy', y );
            if ( isSvg )
            {
                boxPt.setAttribute( 'r', r*1.2 );
            }
            boxPt.setAttribute( 'opacity', opacity*0.8 );
        }
        //Rotate edges:
        for ( i=0;i<boxEdgeElements.length;i++)
        {
            //Similar to stars:
            var boxEdge = boxEdgeElements[i];
            if ( !boxEdge ) continue;
            
            var p1x = parseInt(boxEdge.getAttribute('x1'));
            var p2x = parseInt(boxEdge.getAttribute('x2'));
            var p1y = parseInt(boxEdge.getAttribute('y1'));
            var p2y = parseInt(boxEdge.getAttribute('y2'));
            
            var cx = (p1x + p2x)/2;
            var cy = (p1y + p2y)/2;
            
            p1x = p1x*0.7 + cx*0.3;
            p1y = p1y*0.5 + cy*0.5;
            p2x = p2x*0.7 + cx*0.3;
            p2y = p2y*0.5 + cy*0.5;
            
            boxEdge.setAttribute('x1', p1x);
            boxEdge.setAttribute('x2', p2x);
            boxEdge.setAttribute('y1', p1y);
            boxEdge.setAttribute('y2', p2y);

            if ( boxEdge.forceRedraw )
            {
                boxEdge.forceRedraw();
            }
            
            if ( (p1x-p2x)*(p1x-p2x) + (p1y-p2y)*(p1y-p2y) < 2 )
            {
                boxEdge.parentNode.removeChild( boxEdge );
                boxEdgeElements[i] = null;
                continue;
            }
        }

        if ( boxDetonationTime < -50 )
        {
            //restart:
            spawnBox();                        
        }
    }
    else
    {
        boxSpawnDistance /= 2;

        //Randomise transform axis:
        var cAng = Math.cos( 0.1 );
        var sAng = Math.sin( 0.1 );
        
        boxRotAxis.x += ((Math.random()*100) - 50)/500.0;
        boxRotAxis.y += ((Math.random()*100) - 50)/500.0;
        boxRotAxis.z += ((Math.random()*100) - 50)/500.0;            
        boxRotAxis = v3_normalise( boxRotAxis );
        
        //Cache:
        var ptXs = [];
        var ptYs = [];
        
        var i;
        for ( i=0;i<boxPts.length;i++)
        {
            //Rotate around axis:
            var bp = v3_rotateAround( boxPts[i], boxRotAxis, cAng, sAng );
            ptXs[i] = projectBoxX( bp );
            ptYs[i] = projectBoxY( bp );
            boxPts[i] = bp;
        }
        for ( i=0;i<boxEdgeElements.length;i++)
        {
            var p1 = boxConnectivity[i*2];
            var p2 = boxConnectivity[i*2 + 1];
            
            var boxEdge = boxEdgeElements[i];
            boxEdge.setAttribute( 'x1', ptXs[ p1 ] );
            boxEdge.setAttribute( 'x2', ptXs[ p2 ] );
            boxEdge.setAttribute( 'y1', ptYs[ p1 ] );
            boxEdge.setAttribute( 'y2', ptYs[ p2 ] );

            if ( boxEdge.forceRedraw )
            {
                boxEdge.forceRedraw();
            }
        }
        for ( i=0;i<boxPtElements.length;i++)
        {                    
            var boxPt = boxPtElements[i];
        
            boxPt.setAttribute( 'cx', ptXs[i] );
            boxPt.setAttribute( 'cy', ptYs[i] );
        }
    }
}

function detonateBox()
{
    boxDetonation = true;
    boxDetonationTime = 10;
}

///////////////////////////////////
// Text stuff
var TTS = {"FadeIn":0, "Static":1, "FadeOut":2};

function TextTransition( _text, _yPos, _r, _g, _b )
{
    this.m_text = _text;
    this.m_yPos = _yPos;
    this.m_r = _r;
    this.m_g = _g;
    this.m_b = _b;
    this.discardBlock = function()
    {
        if ( this.m_txtBlock )
        {
            textCanvas.removeChild( this.m_txtBlock );
            this.m_txtBlock = null;
        }
    }
    this.recreateBlock = function( _r, _g, _b, _a )
    {
        this.discardBlock();
        var textBlock = document.createElementNS(svgNS, 'text');
        textBlock.setAttribute('x', starCentreX);
        textBlock.setAttribute('y', _yPos);
        textBlock.setAttribute('font-family', 'Georgia Serif');
        textBlock.setAttribute('font-style', 'italic');
        textBlock.setAttribute('font-size', 18*renderSF);
        if ( isSvg )
        {
            textBlock.setAttribute('fill', 'rgba(255,255,255,0)' );
        }
        else
        {
            textBlock.setAttribute('fill', 'rgb(200,200,200)' );
        }
        var txtNode = document.createTextNode( _text.replace(/ /g, "\u00A0") );
        textBlock.appendChild(txtNode);
        textCanvas.appendChild( textBlock );

        //MUST be in document before this is called:
        textBlock.setAttribute('text-anchor', 'middle');
        this.m_txtBlock = textBlock;
    }
    this.recreateBlock(255,255,255,0);

    this.m_cTimer = 16;
    this.m_cState = TTS.FadeIn;

    this.doTransition = function()
    {
        //Animate:
        if ( g_pageIdx != g_homePageIdx )
        {
            //Remove colouration...
            this.m_r = 200;
            this.m_g = 200;
            this.m_b = 200;
        }

        this.m_cTimer--;

        var r,g,b,a; 

        if ( this.m_cState == 0 )
        {
            var lerp = (this.m_cTimer/16.0);
            r = parseInt((170*lerp)+(this.m_r*(1-lerp)));
            g = parseInt((170*lerp)+(this.m_g*(1-lerp)));
            b = parseInt((180*lerp)+(this.m_b*(1-lerp)));
            a = 1-lerp;
        }
        else if ( this.m_cState == 1)
        {
            r = parseInt(this.m_r);
            g = parseInt(this.m_g);
            b = parseInt(this.m_b);
            a = 1;
        }
        else if ( this.m_cState == 2)
        {
            var lerp = 1.0-(this.m_cTimer/16.0);
            r = parseInt((170*lerp)+(this.m_r*(1-lerp)));
            g = parseInt((170*lerp)+(this.m_g*(1-lerp)));
            b = parseInt((180*lerp)+(this.m_b*(1-lerp)));
            a = 1-lerp;
        }
        if ( isSvg )
        {
            this.m_txtBlock.setAttribute('fill', 'rgba('+r+','+g+','+b+','+a+')' );
        }
        else
        {
            this.m_txtBlock.setAttribute('fill', 'rgb('+r+','+g+','+b+')' );        
        }

        if ( this.m_cTimer > 0 )
        {
            return true;
        }
        if ( this.m_cState<2 )
        {
            this.m_cState++;
            this.m_cTimer = ((this.m_cState==1)?Math.max(16,this.m_text.length):16);
            return true;
        }

        //When done:
        this.discardBlock();
        return false;
    }
}

var textBlocks = ["Start to think outside the box", "Take your mind beyond@the limits of your imagination","","*Philosophy","We work in partnership with our@clients gaining an understanding of@their aspirations and business issues,@in order to enhance and build the capability@and fitness for purpose of their senior@executive and non executive/advisory teams.", "", "*Mission", "Improving organisation performance@by ensuring the organisational capability@is in place to deliver the business strategy."];
var currentTextIsTitle = false;
var titleCountIn = 0;
var textTransitions = [];
var t = 0;

function animateText()
{
    if ( (textTransitions.length == 0 || currentTextIsTitle && titleCountIn--<0) && g_pageIdx == g_homePageIdx )
    {
        var title = false;
        var text = textBlocks[ (t++)%textBlocks.length ]+"@";
        if ( text.substring(0,1) == '*' )
        {
            title = true;
            text = text.substring(1);            
        }
        var p=0, f=0, txtIdx = 0, numTxts = 0;
        while ( (p=text.indexOf('@',f)) != -1 ) {numTxts++;f=p+1;}
        f=0;
        while ( (p=text.indexOf('@',f)) != -1 )
        {
            var subText = text.substring(f,p);
            textTransitions[ textTransitions.length ] = new TextTransition( subText, (title?(starCentreY - 85*renderSF):(starCentreY)) -12*numTxts*renderSF + txtIdx++*24*renderSF, title?255:0,title?255:0,title?255:128 );
            f = p+1;
        }
        currentTextIsTitle = title;
        titleCountIn = 8;
    }

    var i;
    for ( i=0;i<textTransitions.length;i++ )
    {
        if ( !textTransitions[i].doTransition() )
        {
            textTransitions.splice(i,1);
            i--;
        }
    }
}

///////////////////////////////////
//Global:
function animate()
{
    if ( g_editing ) return;
    animateStars();
    animateBox();
    animateText()
}

//This initialises scaling both for SVG elements AND HTML elements:
function initialiseScaling()
{
    var bestWidth = parseInt(GetWindowWidth()) - 50;
    var bestHeight = parseInt(GetWindowHeight()-50);

    //Maintain aspect ratio:
    var sf = Math.min( bestWidth/600, bestHeight/400 );
    if ( sf < 1 && !isIE ) sf = 1;   //Never scale down if FF, render bug in Linux

    bestWidth = parseInt(600*sf);
    bestHeight = parseInt(400*sf);

    var elems = [ GetElem('splashOverlapper'), GetElem('splashContent'), GetElem('splashBackground') ];
    var i;
    for (i=0;i<elems.length;i++)
    {
        elems[i].style.width = bestWidth+"px";
        elems[i].style.height = bestHeight+"px";
    }

    renderWidth = bestWidth;
    renderHeight = bestHeight;
}

//Call on resize:
function reinitialiseSplash()
{
    initialiseScaling();
    initStarParams();
}

function initialiseSplash() 
{
    initialiseScaling();
    createSvgDoc();

    //Spawn some stars:
    initStarParams();
    var i;
    for (i=0;i<(isSvg?40:20);i++)
    {
        spawnStar();
    }
    //Create the box:
    spawnBox();
    
    //Should be called from main animate callback:
    setInterval( 'animate();', 40 );
}

loadHandlers[ loadHandlers.length ] = initialiseSplash;