/*Данный файл писан Фоссой <fossa-artem@mail.ru> в 2009 году и распространяется под GPLv3*/

/*Данный скрипт обеспечивает расширенную функциональность навигатора (эффекты при наведении и обработку щелчков мимо ссылок)*/

//Инициализируем переменные
var navigator_script_loaded = "loaded"; //Маркер того, что скрипт загружен, этот маркер ищит инит-скрипт. После запуска этого (не инита) скрипта, переменная
//принимает значение started

//Элемент 0 массива содержит адрес предидущей страницы, 1 - следующей. Если элемент равен NULL, то соответствующей страницы нет
var navigator_hrefs = new Array(null, null);

//Элемент 0 массива содержит имя идентификатора ссылки на предидущую страницу, 1 - на последующую
var navigator_links_ids = new Array("previous_link", "next_link");

//Двумерный массив. В navigator_elements_groups[0] находится список ID элементов, при клике по которым должен осуществляться переход
//к предыдущей странице, и при наведении мыши на которые должна загораться левая стрелка, а navigator_elements_groups[1], при клике
//по которым должен осуществляться переход к следующей, а при наведении мыши загораться правая стрелка
//ВНИМАНИЕ!!! Элементы, соответствующие стрелкам должны находиться на первом месте
var navigator_elements_groups = new Array(2);
navigator_elements_groups[0] = new Array("navigator_left_arrow", "navigator_left_field", "navigator_left_field_border");
navigator_elements_groups[1] = new Array("navigator_right_arrow", "navigator_right_field_border", "navigator_right_field");

//Элемент 0 массива содержит элемент (или вернее сказать указатель на элемент?), содержащий левую стрелку, 1 - правую. Если элемент массива
//содержит null, то соотвтетствующий элемент страницы не найден
var navigator_target_elements = new Array(null, null);

//Элемент 0 массива содержит текущее состояние левой стрелки, 1 - правой
//Состояние 0 соответствует обычной стрелке, 5 - полностью подсвеченной
var navigator_arrows_states = new Array(0, 0);

//Элемент 0 массива соответствует направлению изменения выделения левой стрелки, 1 - правой
//Изменение расшифровывается следующим образом:
//-1 - выделение стрелки уменьшается,
//0 - нет изменения,
//1 - выделение стрелки увеличивается
var navigator_arrows_dynamics = new Array(0, 0);

//Метка того, что в настоящий момент идёт изменение состояния стрелок и функция обработки ещё будет вызвана
var navigator_arrows_under_processing = false;

//Двумерный массив. В navigator_arrows_filenames[0] находится список из 6 имён файлов левой стрелки, в navigator_arrows_filenames[1] - правой
//Имена должны быть относительными относительно переменной init_base_url. Урлы изображений, которые будут использоваться, дополняются до абсолютных
var navigator_arrows_filenames = new Array(2);
navigator_arrows_filenames[0] = new Array(
"resources/images/interface/navigator_left_arrow0.png",
"resources/images/interface/navigator_left_arrow1.png",
"resources/images/interface/navigator_left_arrow2.png",
"resources/images/interface/navigator_left_arrow3.png",
"resources/images/interface/navigator_left_arrow4.png",
"resources/images/interface/navigator_left_arrow5.png"
);
navigator_arrows_filenames[1] = new Array(
"resources/images/interface/navigator_right_arrow0.png",
"resources/images/interface/navigator_right_arrow1.png",
"resources/images/interface/navigator_right_arrow2.png",
"resources/images/interface/navigator_right_arrow3.png",
"resources/images/interface/navigator_right_arrow4.png",
"resources/images/interface/navigator_right_arrow5.png"
);

//Двумерный массив с изображениями. В navigator_images[0] находится массив предзагруженных изображений для левой стрелке, в navigator_images[1] - для правой.
//Подгружаются только те изображения, которые будут использоваться. Используется только для предварительной загрузки изображений, так как изображение не удаётся
//установить в качестве CSS свойства
var navigator_images = new Array(2);

//Функция входа в скрипт
function navigator_script_init()
{
 var tmp_counter; //Счётчик циклов для разных целей
 var tmp_element; //Временная переменная для хранения элементов
 var elements_counter; //Счётчик элементов
 
 //Пытаемся получить адреса предидущего и последующего элементов а также целевые элементы
 for (tmp_counter = 0; tmp_counter < 2; tmp_counter++)
 {
  //Получаем адреса и подгружаем фоновые изображения
  tmp_element = document.getElementById(navigator_links_ids[tmp_counter]);
  if (tmp_element != null)
  {
   //Ссылка существует, извлекаем href
   navigator_hrefs[tmp_counter] = tmp_element.href;

   //Подгружаем фоновые изображения
   navigator_images[tmp_counter] = new Array();
   for (elements_counter = 0; elements_counter < 6; elements_counter++)
   {
    //Заставляем загружаться изображение, но здесь нигде его не юзаем
    navigator_images[tmp_counter][elements_counter] = new Image(); //Создаём объект изображения
    navigator_arrows_filenames[tmp_counter][elements_counter] = init_base_url + navigator_arrows_filenames[tmp_counter][elements_counter]; //Дополняем урлы нужных изображения до абсолютных
    navigator_images[tmp_counter][elements_counter].src = navigator_arrows_filenames[tmp_counter][elements_counter];
   }
  }

  //И целевые элементы
  tmp_element = document.getElementById(navigator_elements_groups[tmp_counter][0]);
  if (tmp_element != null)
  {
   //Целевой элемент найден
   navigator_target_elements[tmp_counter] = tmp_element;
  }
 }

 //Подключаем обработчики
 //Перебираем группы элементов
 for (tmp_counter = 0; tmp_counter < 2; tmp_counter++)
 {
  //Проверяем, есть ли соответствуюшая этой группе ссылка
  if (navigator_hrefs[tmp_counter] != null)
  //Есть
  {
   //Перебираем элементы
   for (elements_counter = 0; elements_counter < navigator_elements_groups[tmp_counter].length; elements_counter++)
   {
    //Пытаемя получить элемент
    tmp_element = document.getElementById(navigator_elements_groups[tmp_counter][elements_counter]);

    //Смотрим, нашёлся-ли элемент
    if (tmp_element != null)
    {
     //Смотрим, какой у нас браузер (конечно, получается if в цикле, что не есть хорошо, зато нет дублирования кода. А задержка тут надеюсь незаметна
     if (init_browser_type == "IE")
     {
      //Осёл
      tmp_element.attachEvent("onclick", navigator_click_handler); //Обработчик кликов
      tmp_element.attachEvent("onmouseover", navigator_mouseover_handler); //Обработчик помещения мыши на элемент
      tmp_element.attachEvent("onmouseout", navigator_mouseout_handler); //Обработчик ухода мыши с элемента
     }
     else
     {
      //Не осёл
      tmp_element.addEventListener("click", navigator_click_handler, false); //Обработчик кликов
      tmp_element.addEventListener("mouseover", navigator_mouseover_handler, false); //Обработчик помещения мыши на элемент
      tmp_element.addEventListener("mouseout", navigator_mouseout_handler, false); //Обработчик ухода мыши с элемента
     }
    }
   }
  }
 }
}

//Функция принимает имя элемента (element.id) и определяет, к какой группе он принадлежит. Элемент - ссылка (из navigator_links_ids)
//также считается принадлежащим соответствующей группе
//Возвращаемые значения:
//-1 - элемент не принадлежит ни к одной из групп
//0 - элемент принадлежит к группе элементов, ведущих на предидущую страницыу
//1 - элемент принадлежит к группе элементов, ведущих на следующую страницыу
function navigator_get_group_by_element_id(element_id)
{
 var groups_counter; //Счётчик групп элементов
 var elements_counter; //Счётчик элементов в группе

 for (groups_counter = 0; groups_counter < 2; groups_counter++)
 {
  //Перебираем элементы массива элементов навигатора
  for (elements_counter = 0; elements_counter < navigator_elements_groups[groups_counter].length; elements_counter++)
  {
   //Смотрим, не совпал-ли источник заданный элемент с текущим элементом
   if (element_id == navigator_elements_groups[groups_counter][elements_counter])
   {
    //Совпал
    return groups_counter;
   }
  }

  //Проверяем, не принадлежит-ли элемент соответствующей ссылке
  if (element_id == navigator_links_ids[groups_counter])
  {
   //Да, источник - ссылка
   return groups_counter;
  }
 }

 //Перебор закончился, но совпадения не было
 return -1;
}

//Функция обработки клика на элементах навигатора
function navigator_click_handler(event)
{
 //Получаем источник события
 var event_source; //Источник события

 if (init_browser_type == "IE")
 {
  //Для осла
  event_source = window.event.srcElement;
 }
 else
 {
  //Для нормальных браузеров
  event_source = event.target;
 }

 var groups_counter; //Счётчик групп элементов
 var elements_counter; //Счётчик элементов в группе

 //Игнорируем клики по ссылкам (событие от них всплывает к обработчику клика на поле, на котором расположена ссылка)
 if ((event_source.id != navigator_links_ids[0]) && (event_source.id != navigator_links_ids[1]))
 {
  //Клик не на ссылке
  //Смотрим, к какой группе элементов принадлежит источник клика
  var element_group = navigator_get_group_by_element_id(event_source.id);

  //Отправляем браузер по соответствующей ссылке. О проверке на -1 можно не заботиться, ибо к элементу не принадлежащему группе
  //не будет подключен обработчик
  document.location.href = navigator_hrefs[element_group];
 }
}

//Функция обработки помещения мыши на элементы навигатора
function navigator_mouseover_handler(event)
{
 //Получаем источник события
 var event_source; //Источник события

 if (init_browser_type == "IE")
 {
  //Для осла
  event_source = window.event.srcElement;
 }
 else
 {
  //Для нормальных браузеров
  event_source = event.target;
 }

 //Получаем группу элемента, на который наведена мышь
 var element_group = navigator_get_group_by_element_id(event_source.id);

 //Включаем увеличение выделения для соответствующей стрелки
 navigator_arrows_dynamics[navigator_get_group_by_element_id(event_source.id)] = 1;

 //Смотрим, не идёт-ли уже обработка стрелок
 if (!navigator_arrows_under_processing)
 {
  //Нет, ставим метку обработки и вызываем функцию изменения состояния стрелок
  navigator_arrows_under_processing = true;
  navigator_change_state_of_arrows();
 }
}

//Функция обработки выходы мыши за пределы элемента навигатора
function navigator_mouseout_handler(event)
{
 //Получаем источник события
 var event_source; //Источник события

 if (init_browser_type == "IE")
 {
  //Для осла
  event_source = window.event.srcElement;
 }
 else
 {
  //Для нормальных браузеров
  event_source = event.target;
 }

 //Получаем группу элемента, с которого ушла мышь
 var element_group = navigator_get_group_by_element_id(event_source.id);

 //Включаем уменьшение выделения для соответствующей стрелки
 navigator_arrows_dynamics[navigator_get_group_by_element_id(event_source.id)] = -1;

 //Смотрим, не идёт-ли уже обработка стрелок
 if (!navigator_arrows_under_processing)
 {
  //Нет, ставим метку обработки и вызываем функцию изменения состояния стрелок
  navigator_arrows_under_processing = true;
  navigator_change_state_of_arrows();
 }
}

//Функция плавно изменяет степень выделения стрелок на основе их текущего состояния (navigator_arrows_states) и направления изменения выделения (navigator_arrows_dynamics)
//В случае, если после вызова функции направления изменения выделения обеих стрелок не равны 0, функция ставит таймер на вызов самой себя через 0.1 секунды
function navigator_change_state_of_arrows()
{
 //Обрабатываем стрелки
 var tmp_counter;

 for (tmp_counter = 0; tmp_counter < 2; tmp_counter++)
 {
  //Проверяем, не является-ли текущая стрелка отключенной
  if (navigator_hrefs[tmp_counter] != null)
  {
   //Получаем новые состояния стрелок
   navigator_arrows_states[tmp_counter] += navigator_arrows_dynamics[tmp_counter];

   //Проверяем, не достигнуты-ли конечные значения (и нет-ли выхода за них, например в случае быстрого входа и выхода мыши в поле (при этом случается
   //onmouseout при состоянии стрелки равном 0))
   if (navigator_arrows_states[tmp_counter] <= 0)
   {
    navigator_arrows_dynamics[tmp_counter] = 0; //Прекращаем изменение состояния
    navigator_arrows_states[tmp_counter] = 0; //Сбрасываем состояние в 0 - не очень оптимально, но не охота ещё if ставить
   }

   if (navigator_arrows_states[tmp_counter] >= 5)
   {
    navigator_arrows_dynamics[tmp_counter] = 0; //Прекращаем изменение состояния
    navigator_arrows_states[tmp_counter] = 5; //Сбрасываем состояние в 5 - не очень оптимально, но не охота ещё if ставить
   }

   //Применяем новое состояние
   navigator_target_elements[tmp_counter].style.backgroundImage = "url(" + navigator_arrows_filenames[tmp_counter][navigator_arrows_states[tmp_counter]] + ")";
  }
 }

 //Проверяем направления изменения выделения
 if ((navigator_arrows_dynamics[0] != 0) || (navigator_arrows_dynamics[1] != 0))
 {
  //Планируем запуск самой себя
  setTimeout("navigator_change_state_of_arrows()", 100);
 }
 else
 {
  //Это был последний вызов функции, снимаем маркер обработки
  //Нет, ставим метку обработки и вызываем функцию изменения состояния стрелок
  navigator_arrows_under_processing = false;
 }
}