/*
 * Copyright (c) 2003-2012 James Bailie <jimmy@mammothcheese.ca>.
 * All rights reserved.
 *
 * Redistribution and use with or without modification, are permitted
 * provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * The name of James Bailie may not be used to endorse or promote
 * products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * num_fish is the number of fish in the animation.  It may be varied to
 * suit your taste.
 */

var fishes = function( num_fish ) {

   var obj = {},

       num_fish_left  = 6,
       num_fish_right = 6,
       num_turn       = 4,
      
       width          = window.innerWidth || document.documentElement.clientWidth,
       height         = window.innerHeight || document.documentElement.clientHeight,
      
       leftmost       = -100,
       rightmost      = width - 100,
       bottommost     = height - 300,
       level          = 100,
      
       right_trigger  = width / 2,
       left_trigger   = width / 3,
      
       total_leftright = num_fish_left + num_fish_right,
       total           = total_leftright + num_turn,
      
       pix             = [],
       fish            = [],
      
       running         = false,
       swimming        = false;
   
   obj.update_width = function ()
   {
       width          = window.innerWidth || document.documentElement.clientWidth;
       height         = window.innerHeight || document.documentElement.clientHeight;
       rightmost      = width - 120;
       bottommost     = height - 300;
       right_trigger  = width / 2;
       left_trigger   = width / 3;
   }
   
   obj.go = function()
   {
      if ( running )
         return;
      
      running = true;
      animate();
   }
   
   obj.init = function()
   {
      var i = 0, j = 0;
      var body = document.getElementsByTagName( 'body' )[ 0 ];
      var html = '', hsh, elt;
         
      if (( hsh = window.location.hash ) &&
          ( elt = document.getElementById( hsh.substring( 1 ))))
         elt.style.backgroundColor = '#e0e0e0';
   
      for( ; i < num_fish; ++i )
      {
         html += '<div id="layer' + i +
                 '" class="fish" style="position: absolute; display: none">' +
                 '<img id="fish' + i + '" src="/fish0.png" style="border: none;" alt="" /></div>';
      }
   
      body.innerHTML += html;
   
      for( i = 0; i < total; ++i )
         pix[ i ] = new Image();
   
      pix[ 11 ].src = '/fish0.png';
      pix[ 10 ].src = '/fish1.png';
      pix[ 9 ].src = '/fish2.png';
      pix[ 8 ].src = '/fish1.png';
      pix[ 7 ].src = '/fish0.png';
      pix[ 6 ].src = '/fish5.png';
   
      pix[ 5 ].src = '/fish6.png';
      pix[ 4 ].src = '/fish7.png';
      pix[ 3 ].src = '/fish8.png';
      pix[ 2 ].src = '/fish7.png';
      pix[ 1 ].src = '/fish6.png';
      pix[ 0 ].src = '/fish11.png';
   
      for( i = total_leftright; i < total; ++i )
         pix[ i ].src = '/turn' + j++ + '.png';
   
      for( i = 0; i < num_fish; ++i )
      {
         fish[ i ] = {}

         fish[ i ].frame = 0;
         fish[ i ].img   = document.getElementById( 'fish' + i );
         fish[ i ].layer = document.getElementById( 'layer' + i );
         fish[ i ].where = leftmost;
         fish[ i ].dec   = i % 10 + 2;
         fish[ i ].turn  = 0;
         fish[ i ].delay = 0;
         fish[ i ].top   = level;

         reset( fish[ i ] );
      }
   }

   function reset( fishie )
   {
      fishie.where = -( Math.round( Math.random() * 350 ) + 350 );
      fishie.top   = level + Math.round( Math.random() * 300 );
      fishie.turn  = 0;
      
      fishie.layer.style.display = 'block';
      fishie.layer.style.left = fishie.where + 'px';
      fishie.layer.style.top = fishie.top + 'px';
      
      fishie.frame = Math.floor( Math.random() * num_fish_right ) + num_fish_right;
      fishie.img.src = pix[ fishie.frame ].src;
   }
   
   function swim( fishie )
   {
      flip( fishie );
      move( fishie );
   }
   
   function flip( fishie )
   {
      if ( fishie.turn >= total_leftright )
      {
         fishie.img.src = pix[ fishie.turn ].src;
   
         if ( ++fishie.delay < 2 )
            return;
   
         fishie.delay = 0;
   
         if ( ++fishie.turn == total )
         {
            fishie.turn = 1;
            fishie.delay = 0;
            fishie.frame = Math.floor( Math.random() * num_fish_left );
         }
      }
      else
      {
         var limit = ( fishie.turn ? num_fish_left : total_leftright );
   
         if ( ++fishie.delay < 3 )
            return;
   
         fishie.delay = 0;
   
         if ( ++fishie.frame == limit )
            fishie.frame = ( fishie.turn ? 0 : num_fish_left );
   
         fishie.img.src = pix[ fishie.frame ].src;
      }
   }

   function move( fishie )
   {
      if ( fishie.turn == 0 )
      {
         if ( fishie.where > rightmost )
            fishie.turn = total_leftright;
         else
         {
            if ( fishie.where > right_trigger )
               fishie.where += fishie.dec;
            else
               fishie.where += 3;
   
            fishie.layer.style.left = fishie.where + 'px';
         }
   
         swimming = true;
      }
      else if ( fishie.turn == 1 )
      {
         if ( fishie.where > leftmost )
         {
            if ( fishie.where > right_trigger || fishie.where < left_trigger )
               fishie.where -= fishie.dec;
            else
               fishie.where -= 3;
   
            fishie.layer.style.left = fishie.where + 'px';
            swimming = true;
         }
      }
      else
         swimming = true;
   }

   function animate()
   {
      var i;
   
      swimming = false;
   
      for( i = 0; i < num_fish; ++i )
         swim( fish[ i ] );
   
      if ( swimming )
         setTimeout( animate, 20 );
      else
      {
         if (( level += 200 ) > bottommost )
            level = 10;
   
         for( i = 0; i < num_fish; ++i )
            reset( fish[ i ] );
   
         running = false;
      }
   }

   return obj;

}( 25 );

window.onload = fishes.init;
window.onresize = fishes.update_width;

