/************************************************************
* Библиотека написана Systemnik'om (Михалицын Александр):   *
* <systemnikass@yandex.ru> (ICQ:6493185);                   *
* http://systemnik.net.ru.                                  *
* Вы можете использовать библиотеку без ограничений         *
* если поставите ссылку сюда:                               *
* http://forum.systemnik.net.ru/viewtopic.php?t=1           *
* В комерческих целях скрипт использовать запрещено,        *
* модификации разрешены и приветствуется их публикация тут: *
* http://forum.systemnik.net.ru/viewforum.php?f=7           *
* Поддержку вы можете получить тут:                         *
* http://forum.systemnik.net.ru/viewforum.php?f=6           *
* Огромное спасибо:                                         *
* Furax                                                     *
* Name: snow.js library                                     *
* Version: 2.7                                              *
************************************************************/
function Class_snowfall()
{
   // Константы
   var snow_consts = new Array();
   snow_consts["borderForce"] = 0.01; //Сила отталкивания от краёв; изменять именно эту константу
   snow_consts["g"] = 54;
   snow_consts["m"] = 0.1;
   snow_consts["k"] = 0.1;
   snow_consts["F"] = 20;
   snow_consts["dt"] = 1;
   snow_consts["mouseX"] = -1000;
   snow_consts["mouseY"] = -1000;

   // Интервал для вызова метода flakes_positions
   var positions;

   // Объявление конфигурационного массива
   var settings = new Array();

   // Настройки
   settings[0] = true;   //Использовать ли изображения
   settings[1] = "*";    //Символ "снежинки"
   settings[2] = "/i/"; //Имя папки с изображениями
   settings[3] = ".gif"; //Расширения
   settings[4] = 5;      //Количество "видов" снежинок
   settings[5] = 41;     //Количество "объектов" снежинок
   settings[6] = 'blue'; // Цвет текстовых снежинок

   /**
    * Кэшируем изображения если они включены.
    */
   if (settings[0])
   {
      var imgs = new Array();
      for (var numimg = 1; numimg <= settings[4]; numimg++)
      {
         imgs[numimg] = new Image();
         imgs[numimg].src = settings[2] + '/' + numimg + settings[3];
      }
   }

   /**
    * Метод изменит значение переменных
    * snow_consts["mouseX"] и snow_consts["mouseY"] записав в них
    * координаты мыщи.
    */
   function mouse_Coords(event)
   {
      var event = event || window.event;
      snow_consts["mouseX"] = event.clientX;
      snow_consts["mouseY"] = event.clientY;
   }

   document.getElementsByTagName("body")[0].onmousemove = mouse_Coords;

   /**
    * Метод создает settings[5] снежинок
    * задавая им все необходимые свойства.
    */
   function create_flakes()
   {
      var clientWidth = document.getElementsByTagName("body")[0].clientWidth;
      var clientHeight = document.getElementsByTagName("body")[0].clientHeight;
      var body_element = document.getElementsByTagName("body")[0];
      for (var id=1; id<=settings[5]; id++) /* На каждой итерации цикла создается снежинка */
      {
         var flake_tag = 0;
         if (settings[0]) // Выбор тега снежинки в зависимсти от опции settings[0]
         {
            flake_tag = 'img';
         } else {
            flake_tag = 'div';
         }
         flake_obj = document.createElement(flake_tag); /* Задаются все необходимые свойства. */
         if (settings[0]) /* Создание объекта снежинки в зависимости от опции settings[0] */
         { 
            var random_num = Math.floor(Math.random() * settings[4]) + 1;
            flake_obj.src = imgs[random_num].src; 
            flake_obj.alt = "flake" + id; 
         } else { 
            flake_obj.appendChild(document.createTextNode(settings[1])); 
         }
         flake_obj.id = 'flake'+id;
         flake_obj.style.color = settings[6];
         var flake_obj = body_element.appendChild(flake_obj); /* Вставляем нашу снежинки в тег body */
         flake_obj.halfWidth = flake_obj.clientWidth/2;  /* Радиус снежинки */
         flake_obj.halfHeight = flake_obj.clientHeight/2;/* Высота снежинки */
         flake_obj.style.position = "absolute";
         flake_obj.left = Math.random() * (clientWidth - flake_obj.halfWidth); /* Два специальных свойства с целью работы скорости снежинок, так как style.left и top может хранить только целые значения. */
         flake_obj.top = Math.random() * (clientHeight - flake_obj.halfHeight - snow_consts["g"]);
         flake_obj.amplitude = 1 + Math.random(); /* Отклонение от оси */
         flake_obj.speed = 1 + Math.random() * 0.2; /* Скорость падения */
         flake_obj.tempo = 2*Math.PI/(80 + 80 * Math.random()); /* Скорость покачивания */
         flake_obj.speedX = 0; /* В этих свойствах ранится разгон */
         flake_obj.speedY = 0;
      }
   }

   function delete_flakes()
   {
      var body_element = document.getElementsByTagName("body")[0];
      for (var id=1; id<=settings[5]; id++)
      {
         var flake_obj = document.getElementById('flake' + id);
         body_element.removeChild(flake_obj);
      }
   }

   function flakes_positions()
   {
      var clientWidth = document.getElementsByTagName("body")[0].clientWidth; /* Переменные для удобства */
      var clientHeight = document.getElementsByTagName("body")[0].clientHeight;
      var scrollLeft = document.getElementsByTagName("body")[0].scrollLeft;
      var scrollTop = document.getElementsByTagName("body")[0].scrollTop;
      for (var i=1; i<=settings[5]; i++)                        /* Изменение положения снежинки на итерации цикла */
      {
         var flake_obj = document.getElementById('flake'+i); /* Получаем объект снежинки */
         flake_obj.left += (flake_obj.speedX + flake_obj.amplitude*Math.cos(flake_obj.top*flake_obj.tempo))*snow_consts["dt"];
         /* Выше! Это свойство создано с целью работы разных скоростей снежинок так как style.left может хранить только 
         цельные значения. */
         flake_obj.top += (flake_obj.speedY + flake_obj.speed)*snow_consts["dt"];
         /* Выше! Это свойство создано с целью работы разных скоростей снежинок так как style.left может хранить только 
         цельные значения. */
         if (flake_obj.top < - snow_consts["g"]) /* Проверка не вышла ли снежинка за край экрана */
         {
            flake_obj.top = -snow_consts["g"];
            flake_obj.speedX = flake_obj.speedY = 0; /* Обнуляем разгон! */
         } else {
            if (flake_obj.top > (clientHeight - snow_consts["g"])) /* Снежинка вышла за край изменяем положение. */
            {
               flake_obj.style.top = scrollTop;
               flake_obj.top = - snow_consts["g"];
               flake_obj.speedX = flake_obj.speedY = 0; /* Обнуляем разгон! */
               flake_obj.style.left = Math.floor(flake_obj.left = Math.random() * (clientWidth - flake_obj.halfWidth)) + scrollLeft; 
            }
         }
         var deltaX = flake_obj.left + flake_obj.halfWidth - snow_consts["mouseX"];            /* Начинаем вычислять left и top координаты в зависимости от положения мыщи */
         var deltaY = flake_obj.top + flake_obj.halfHeight/2 - snow_consts["mouseY"];
         var Fx_old = snow_consts["F"] * deltaX/(deltaX*deltaX + deltaY*deltaY) - snow_consts["k"]*flake_obj.speedX;
         var Fx = Fx_old + snow_consts["borderForce"] * (Math.max(snow_consts["g"] - flake_obj.left, 0) - Math.max(flake_obj.left - clientWidth + 2*snow_consts["g"], 0));
         var Fy = snow_consts["F"] * deltaY/(deltaX*deltaX + deltaY*deltaY) - snow_consts["k"]*flake_obj.speedY;
         flake_obj.speedX += Fx/snow_consts["m"]*snow_consts["dt"];
         flake_obj.speedY += Fy/snow_consts["m"]*snow_consts["dt"];
         flake_obj.style.left = scrollLeft + Math.round(flake_obj.left) + 'px'; /* Устанавливаем координаты! */
         flake_obj.style.top = scrollTop + Math.round(flake_obj.top) + 'px';
      }
   }

   this.start = function()
   {
      create_flakes(); /* Создаем снежинки */
      positions = setInterval(flakes_positions, 40); /* Запускаем метод flakes_positions каждые 40 миллисекунд */
   }

   this.stop = function()
   {
      clearInterval(positions);
      delete_flakes();
   }
}

var snowfall = new Class_snowfall();
