/*
  Snowflakes plugin
  (P) PSNet, 2008 - 2011
  http://psnet.lookformp3.net/
*/

var ls = ls || {};

ls.snowflakes = (function ($) {

  this.Settings = {
    'use_images': true,
    'flake_symbol': '*',
    'flake_imgs_ext': 'gif',
    'flake_types_num': 1,
    'flake_objects_num': 41,
    'update_positions_interval': 40,
  },

  this.Constants = {
    'borderForce': 0.01, // Сила отталкивания от краёв
    'g': 60,
    'm': 0.1,
    'k': 0.1,
    'F': 20,
    'dt': 1,
    'mouseX': -1000,
    'mouseY': -1000,
  },

  this.CallProcID = '';

  this.Snowflakes_Enabled = false;
  
  // ---

  this.CacheImages = function () {
    if (this.Settings['use_images']) {
      this.imgs = new Array();
      for (var numimg = 1; numimg <= this.Settings ['flake_types_num']; numimg ++) {
        this.imgs [numimg] = new Image ();
        this.imgs [numimg].src = Snowflakes_Images_Dir + numimg + '.' + this.Settings ['flake_imgs_ext'];
      }
    }
  }
  
  // ---

  this.Mouse_Moves = function (event) {
    var event = event || window.event;
    ls.snowflakes.Constants ["mouseX"] = event.clientX;
    ls.snowflakes.Constants ["mouseY"] = event.clientY;
  }

  // ---

  this.Create_Flakes = function () {
    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 <= this.Settings ['flake_objects_num']; id++) {
      var flake_tag = 0;
      if (this.Settings['use_images']) {
        flake_tag = 'img';
      } else {
        flake_tag = 'div';
      }
      flake_obj = document.createElement (flake_tag);
      if (this.Settings['use_images']) {
        var random_num = Math.floor (Math.random () * this.Settings ['flake_types_num']) + 1;
        flake_obj.src = this.imgs [random_num].src;
        flake_obj.alt = "Flake_" + id;
      } else {
        flake_obj.appendChild (document.createTextNode (this.Settings ['flake_symbol']));
      }
      flake_obj.id = 'flake'+id;
      flake_obj.className = 'Snowflakes_Images';
      var flake_obj = body_element.appendChild(flake_obj);
      
      flake_obj.halfWidth = flake_obj.clientWidth/2;  /* Радиус снежинки */
      flake_obj.halfHeight = flake_obj.clientHeight/2;/* Высота снежинки */

      flake_obj.left = Math.random() * (clientWidth - flake_obj.halfWidth);
      flake_obj.top = Math.random() * (clientHeight - flake_obj.halfHeight - this.Constants["g"]);
      /* Два специальных свойства с целью работы скорости снежинок, так как style.left и top может хранить только целые значения. */
      
      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;
    }
  }
  
  // ---

  this.Delete_Flakes = function () {
    var body_element = document.getElementsByTagName ("body") [0];
    for (var id = 1; id <= this.Settings ['flake_objects_num']; id ++) {
      var flake_obj = document.getElementById ('flake' + id);
      body_element.removeChild (flake_obj);
    }
  }
  
  // ---

  this.Move_Flakes = function () {
    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 <= ls.snowflakes.Settings ['flake_objects_num']; 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)) * ls.snowflakes.Constants ["dt"];
      flake_obj.top += (flake_obj.speedY + flake_obj.speed) * ls.snowflakes.Constants ["dt"];
      /* Эти свойства созданы с целью работы разных скоростей снежинок так как style.left и top могут хранить только цельные значения. */

      if (flake_obj.top < - ls.snowflakes.Constants ["g"]) { /* Проверка не вышла ли снежинка за край экрана */ 
        flake_obj.top = -ls.snowflakes.Constants ["g"];
        flake_obj.speedX = flake_obj.speedY = 0; /* Обнуляем разгон! */
      } else {
        if (flake_obj.top > (clientHeight - ls.snowflakes.Constants ["g"])) { /* Снежинка вышла за край, изменяем положение. */
          flake_obj.style.top = scrollTop;
          flake_obj.top = - ls.snowflakes.Constants ["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 - ls.snowflakes.Constants ["mouseX"];
      var deltaY = flake_obj.top + flake_obj.halfHeight / 2 - ls.snowflakes.Constants ["mouseY"];
      /* Начинаем вычислять left и top координаты в зависимости от положения мыши */
      
      var Fx_old = ls.snowflakes.Constants["F"] * deltaX/(deltaX*deltaX + deltaY*deltaY) - ls.snowflakes.Constants["k"]*flake_obj.speedX;
      var Fx = Fx_old + ls.snowflakes.Constants["borderForce"] * (Math.max(ls.snowflakes.Constants["g"] - flake_obj.left, 0) - Math.max(flake_obj.left - clientWidth + 2*ls.snowflakes.Constants["g"], 0));
      var Fy = ls.snowflakes.Constants["F"] * deltaY/(deltaX*deltaX + deltaY*deltaY) - ls.snowflakes.Constants["k"]*flake_obj.speedY;
      flake_obj.speedX += Fx/ls.snowflakes.Constants["m"]*ls.snowflakes.Constants["dt"];
      flake_obj.speedY += Fy/ls.snowflakes.Constants["m"]*ls.snowflakes.Constants["dt"];
      
      flake_obj.style.left = scrollLeft + Math.round(flake_obj.left) + 'px';
      flake_obj.style.top = scrollTop + Math.round(flake_obj.top) + 'px';
    }
  }
  
  // ---

  this.Enable_Snowflakes = function (New_Settings) {
    if (this.Snowflakes_Enabled) {
      this.Stop_Snowflakes ();
    }
    
    if (New_Settings) {
      this.Settings = $.extend ({}, this.Settings, New_Settings);
    }
    
    this.CacheImages ();

    this.Create_Flakes ();
    this.CallProcID = setInterval (this.Move_Flakes, this.Settings ['update_positions_interval']);

    this.Snowflakes_Enabled = true;
  }
  
  // ---

  this.Stop_Snowflakes = function() {
    if (!this.Snowflakes_Enabled) return false;

    clearInterval (this.CallProcID);
    this.Delete_Flakes ();

    this.Snowflakes_Enabled = false;
  }

  // ---
  
  return this;

}).call (ls.snowflakes || {}, jQuery);

