// -------------------------------------------------  onLoad -----------------------------------------------------

addOnload(
  function() {
    //new Draggable('message_win');
  }
);

// -------------------------------------------------  AJAX -----------------------------------------------------
var ajax_status = 0;
var ajax_loader = true;
Ajax.Responders.register({
  onCreate: function() {
    overlayShow($('overlay_ajax'),0);
    if (ajax_loader)
      popupShow($('ajax_loading'));
    $('overlay_ajax').style.cursor = "wait";
    ajax_status++;

  },
  onComplete: function() {
    if (!--ajax_status) {
      popupHide($('ajax_loading'));
      overlayHide($('overlay_ajax'));
      $('overlay_ajax').style.cursor = "default";
    }


  },
  onFailure: function() {
    if (!--ajax_status) {
      popupHide($('ajax_loading'));
      overlayHide($('overlay_ajax'));
      $('overlay_ajax').style.cursor = "default";
    }
  }
});

function addOnload(newFunction) {
  var oldOnload = window.onload;
  window.onload = function() {
    if (typeof oldOnload == "function") {
      oldOnload();
      newFunction();
    }
    else {
      newFunction();
    }
  }
}
// ----------------------------------------- Event ---------------------------------------------------
// obj.onclick = eventPrevent;   $('user_form').onsubmit = eventPrevent;
// or handler:   handler(event) { eventPrevent(event) }
var eventPrevent = function (oEvent) {
  if (window.event) {
    oEvent = window.event;
    oEvent.returnValue = false;
  } else {
    oEvent.preventDefault();
  }
}



var cancleBubbling = function(oEvent) {
  if (window.event) {
    window.event.cancelBubble = true;
  }
  else {
    oEvent.stopPropagation();
  }
}

function checkRequest(request, set_mes, out) {

  pattern = /^\{(.+?)\}((.|\n)*)$/m;
  //pattern = /^\{(.+?)\}(.*)$/;
  result = request.match(pattern);
  //alert(result[0] + '\n' + result[1] + '\n' +result[2] + '\n');

  // неопределенный ответ / ошибка в скрипте
  if (result == null && set_mes) {
      setMessage('Ошибка при передаче данных с сервера', 'error');
  if (out) exit;
  else return false;
  }

  // error
  if (result != null && (result[1] == "error")  && set_mes) {
    setMessage(result[2], result[1]);
    if (out) exit;
    else return false;
  }

  // exclamation    Есть возможность автоматом вывести message
  if (result != null && (result[1] == "exclamation")  && set_mes) {
    setMessage(result[2], result[1]);
    if (out) exit;
    else return "exclamation";    // это true но так же "info"
  }

  // info    Есть возможность автоматом вывести message
  if (result != null && (result[1] == "info")  && set_mes) {
    setMessage(result[2], result[1]);
    if (out) exit;
    else return "info";    // это true но так же "info"
  }

  // ok / для дальнейшей обработки
  if (result != null && result[1] == "ok") {   return "ok";   }   // это true но так же "ok"

  // other / для дальнейшей обработки
  if (result != null)  {   return result[1];   }

  return false; // а вдруг
}






// -------------------------------------------------  Message -----------------------------------------------------

function setMessage(message, style) {
  // Не плохо было бы сделать класс
  //if (style=='error') head = 'error';
  var head_logo = "<img class='img_center' src='../images/" + style + "_20.png' style='margin-left: -3px;' />";
  var content = "<div class=" + style + ">" + message + "</div>";
  msgWinOutput(content, head_logo, 0.3, 500, null );
}

var scroll = false;
function msgWinOutput(content, head, opacity, width, height) {

  if (typeof(head) == 'undefined' || head == null)  head = '';
  if (typeof(opacity) == 'undefined' || opacity == null)  opacity = 0.3;

  $('message_win_head').innerHTML = head;

  if (typeof(content) == 'object') {
    $('message_win_content').appendChild(content);
  }
  else {
    $('message_win_content').innerHTML = content;
/*    if ($('message_win_content').innerHTML =="")       // если сразу несколько outputs
      $('message_win_content').innerHTML = content;
    else {
      $('message_win_content').innerHTML += content;     // больше проблем
    }                                                                       */
  }
  if ($('message_win_tab').style.display = "none")   // может быть закрыт header (шкала). универсальный popup
    $('message_win_tab').style.display = "block"

  $('message_win').style.display = "block";       // только после display появится clientWidth

  var content_width = $('message_win_content').clientWidth;


  // output width <= width
/*if ( typeof(width) != 'undefined' && width != null )
     if ( content_width > width ) content_width = width;
   if  (content_width > 850) content_width = 850;
  if  (content_width < 250) content_width = 250; */

  // output width = width
  if (typeof(width) != 'undefined' && width != null && width<850)  $('message_win_content').style.width = width + 'px';
  var content_width = $('message_win_content').clientWidth;
  if  (content_width > 850) content_width = 850;
  if  (content_width < 250) content_width = 250;

  if (typeof(height) != 'undefined' && height != null )  $('message_win_content').style.height = height + 'px';

    //  alert('style.width - ' + $('message_win_content').style.width + "\n" + 'clientWidth - ' + $('message_win_content').clientWidth + "\n" + 'style.height - ' + $('message_win_content').style.height + "\n" + 'clientHeight - ' + $('message_win_content').clientHeight);

  if ($('message_win_content').clientHeight > 450) {
    $('message_win_content').height = 450 + 'px';
    $('message_win_content').style.overflow = "scroll";
    content_width = $('message_win_content').scrollWidth + 10;
    if  (content_width > 860) content_width = 860;
    if  (content_width < 260) content_width = 260;
    scroll = true;
    $('message_win_content').style.width = content_width + "px";
    content_width += 10;
  }

  $('message_win').style.width = (content_width + 2) + "px";  // очень странно: если нет + 1 (как мин. 1), то в IE scroll не сбрасывается

  $('message_win').style.display = "none";

  overlayShow($('overlay'), opacity);
  popupShow($('message_win'));
}

addOnload(function() {
    Event.observe('message_win_close', 'click', hideMessageWin);
    //Event.observe('message_win', 'click', hideMessageWin);
  }
);

function hideMessageWin() {
  popupHide($('message_win'));
  $('message_win').style.width = "auto";
  $('message_win_content').style.width = "auto";
  //$('message_win_content').style.height = "auto";
  $('message_win_head').innerHTML = "";
  $('message_win_content').innerHTML = "";
  if (scroll) {
    $('message_win_content').style.overflow = "auto";
    scroll = false;
    }
  overlayHide($('overlay'));
}

/*function unsetMessage() {                 // ????????? need
  //$('message').innerHTML = "";     // проподает message при AJAX
  $('message').style.height = "1px";
}*/

// --------------------------------- Animation ----------------------------------------
var animation_status = false;

function showAnimation(dest){
  animation_status = true;
  f = function()  {
    output(dest);             
  };
  dest.style.display = "block";
  dest.style.height = "1px";    // for IE (0px => auto(defined from content))
  max = dest.scrollHeight;  // scrollHeight v FF poluchaet znachenie tolko posle style.height = 1px
  //alert(max);
  if (max>150) {
    dest.style.height =  max + "px";
    animation_status = false;
    return;
  }
  //var interval = Math.ceil(2000/max);
  var interval = 50;
  id = setInterval(f, interval);
}
function output(dest) {
  dest.style.height = parseInt(dest.style.height) + 8 + "px";
  if (parseInt(dest.style.height) > max) {
    dest.style.height =  max + "px";
    animation_status = false;
    clearInterval(id);
  }
}

function hideAnimation(dest){
  animation_status = true;
  height = parseInt(dest.style.height);
  if (height > 150) {
    dest.style.height =  0 + "px";
    dest.innerHTML = "";
    animation_status = false;
    return;
  }
  fa = function()  {
    outputHide(dest);
  };
  id2 = setInterval(fa, 50);
}
function outputHide(dest) {
  //$('page').innerHTML = $('page').innerHTML + "real height = " + dest.style.height + " - ";
  height = height - 8;
  //$('page').innerHTML = $('page').innerHTML + "height = " + height + " - ";
  if (height <= 0) {
    //$('page').innerHTML = $('page').innerHTML + " mi tut - ";
    dest.style.height =  0 + "px";
    dest.innerHTML = "";
    animation_status = false;
    clearInterval(id2);
    //return false;
  }
  else {
    dest.style.height = height + "px";
  }
  //$('page').innerHTML = $('page').innerHTML + "real height = " + dest.style.height + "<br/>";
}


// ------------------------ Animation - blinker ---------------------------------

function uniqueInteger() {                    // решил без него
    // Increment and return our "static" variable
    return uniqueInteger.counter++;
}
var counter;
function blink(dest, color)
{
  dest.blur();
  counter=0;
  //uniqueInteger.counter = 0;
  f = function() {
    //blinker = uniqueInteger();
    if (counter % 2 == 0) {
      dest.style.backgroundColor = color;
    }
    else {
      dest.style.backgroundColor = "#FFFFFF";
    }
    if (counter++ == 5){
      clearInterval(id);
     }
  }
  id = setInterval(f, 100);
}

// ---------------- Приводит к фоормату 1 234 567.89
function formatDouble(n){
  n = n.toFixed(2);
  var s = String(n);
  var k = s.indexOf(".");
/*  if (k < 0) {
      k = s.length;
      s += ".00";
  } else {
      s += "00"
  }*/
  s = s.substr(0, k + 3);
  for (var i = k - 3, j = n < 0 ? 1 : 0; i > j; i -= 3) s = s.substr(0, i) + " " + s.substr(i);
  return s;
}

// ----------------------------------------- popup window-------------------------------------------
function popupShow(dest) {
  // document.documentElement.clientHeight видимая область
  // document.documentElement.scrollWidth все
  // document.documentElement.scrollTop (невидимая scroll, то что в данный момент не видно)

  dest.style.display = "block";

  dest.style.top = (document.documentElement.clientHeight/2 -
    dest.scrollHeight/2 + document.documentElement.scrollTop) + "px";
  dest.style.left = (document.documentElement.clientWidth/2 -
     dest.scrollWidth/2 + document.documentElement.scrollLeft) + "px" ;
  dest.style.visibility = "visible";
}

function popupHide(dest) {
  dest.style.visibility = "hidden";
  dest.style.display = "none";
}

// ----------- не задействована
function  popupShowHide(dest){
          dest.style.opacity = "1.0";    // а вдруг смогут кликнуть во время fade
          dest.style.filter = "alpha(opacity=100)";
          popupShow(dest);
          overlayShow($('overlay'),0);
          id = setTimeout("overlayHide($('overlay'));", 2000); // не могут кликнуть во время fade
          Effect.Fade(dest.id, { duration: 2.0 });
}

// ------------------- overlay ----------------------------
function overlayShow(dest, opacity) {
  // opacity [0-1]
  // document.documentElement.scrollWidth все
  //alert(document.documentElement.scrollWidth + " - " + document.documentElement.scrollHeight);
  dest.style.height = document.documentElement.scrollHeight + "px";
  dest.style.width = document.documentElement.scrollWidth + "px";
  dest.style.display = "block";
  dest.style.opacity = opacity;
  dest.style.filter = "alpha(opacity=" + opacity*100 + ")";
  //dest.style.display = "block";
}
function overlayHide(dest) {
  dest.style.display = "none";
}



// ------------------------------------------ Calender -------------------------------------

function checkCalender(date1, date2, cal_interval){
 // if (date1=="" && date2=="")      return false;
  parse_date1 = parseDate(date1);
  parse_date2 = parseDate(date2);
  if (parse_date1 && parse_date2 && (parse_date2 - parse_date1) < 0 ) {
    alert ('Неверно выбраны даты');
    return false;
  }
 // if (!parse_date1 && !parse_date2)     return false;
  getOrders(1, null, null, null, date1, date2, cal_interval);
}

function resetCalender() {
  $('f_date1').value = '';
  $('f_date2').value = '';
  $('cal_interval').selectedIndex = 0;
  getOrders(1, null, null, null, '', '', 0);
}
// string  xxxx-xx-xx to date
function parseDate(str) {
  if (str == "") return false;
  var pattern = /(\d{4})-(\d{2})-(\d{2})/;
  var result = str.match(pattern);
  if (result == null) return false;
  var date = new Date(result[1] , result[2]-1 , result[3]);
  return date;
}

// Uneversal !!! ------------------------------------------------
// date            dd.mm.yyyy || yyyy-mm-dd || date
// output_format   dd.mm.yyyy || yyyy-mm-dd || yyyymmdd (for MySQL) || date
function parseDate2(date, output_format) {
  // str dd.mm.yyyy
  if ( /^\d{2}\.\d{2}\.\d{4}$/.test(date)) {
    var result = date.match(/(\d{2})\.(\d{2})\.(\d{4})/);
    _date = new Date(result[3] , result[2]-1 , result[1]);
  }
  // str yyyy-mm-dd
  else if ( /^\d{4}-\d{2}-\d{2}$/.test(date)) {
    var result = date.match(/^(\d{4})-(\d{2})-(\d{2})$/);
    _date = new Date(result[1] , result[2]-1 , result[3]);
  }
  // Date object
  else if (typeof date == 'object' && date instanceof Date) {
    _date = date;
  }
  else {
    return  '';
  }

  var day = _date.getDate().toString();
  day = (day.length == 1) ? ('0' + day) : day;
  var month = (_date.getMonth() + 1).toString();
  month = (month.length == 1) ? ('0' + month) : month;

  var year = _date.getFullYear();

  switch (output_format) {
    case 'dd.mm.yyyy':
      return   day + '.' + month + '.' + year;
    break;
    case 'yyyy-mm-dd':
      return   year + '-' + month + '-' + day;
    break;
    case 'yyyymmdd':
      return   parseInt(year +  month + day);
    break;
    case 'date':
      return   _date;
    break;
  }
}


//date to string xxxx-xx-xx
function dateToString(date) {

  var month = (date.getMonth() + 1).toString();
  month = (month.length == 1) ? ('0' + month) : month;

  var day = date.getDate().toString();
  day = (day.length == 1) ? ('0' + day) : day;

  var str = date.getFullYear() + '-' + month + '-' + day;
  return str;
}

// выставляем интервал в календаре из select
function setCalendarInterval(src) {
  date_interval = src.options[src.selectedIndex].text;
  var today = new Date();
  var today_year = today.getFullYear();
  var today_month = today.getMonth();
  var today_date = today.getDate();
  var today_day = (today.getDay() == 0) ? 7 : today.getDay();   // (1-7) instead (1-6,0)
  switch (date_interval) {
    case '':
    case 'все':
      $('f_date1').value = '';
      $('f_date2').value = '';
      break;
    case 'сегодня':
      $('f_date1').value = dateToString(today);
      $('f_date2').value = dateToString(today);
      break;
    case 'вчера':
      var yesterday = new Date();
      yesterday.setDate(today_date - 1);
      $('f_date1').value = dateToString(yesterday);
      $('f_date2').value = dateToString(yesterday);
      break;
    case 'эта неделя':
      var this_week_begin = new Date();
      this_week_begin.setDate( today_date -  today_day + 1 );
      var this_week_end = new Date(this_week_begin.getFullYear(), this_week_begin.getMonth(), this_week_begin.getDate() + 6 );
      $('f_date1').value = dateToString(this_week_begin);
      $('f_date2').value = dateToString(this_week_end);
      break;
    case 'прошлая неделя':
      var last_week_begin = new Date();
      last_week_begin.setDate( (today_date - 7) - today_day + 1 );
      var last_week_end = new Date(last_week_begin.getFullYear(), last_week_begin.getMonth(), last_week_begin.getDate() + 6 );
      $('f_date1').value = dateToString(last_week_begin);
      $('f_date2').value = dateToString(last_week_end);
      break;
    case 'этот месяц':
      var this_month_begin = new Date(today_year, today_month, 1);
      var this_month_end = new Date(today_year, today_month + 1, 0);
      $('f_date1').value = dateToString(this_month_begin);
      $('f_date2').value = dateToString(this_month_end);
      break;
    case 'прошлый месяц':
      var last_month_begin = new Date(today_year, today_month - 1, 1);
      var last_month_end = new Date(today_year, today_month, 0);
      $('f_date1').value = dateToString(last_month_begin);
      $('f_date2').value = dateToString(last_month_end);
      break;
    case 'с начала года':
      var this_year_begin = new Date(today_year, 0, 1);
      $('f_date1').value = dateToString(this_year_begin);
      $('f_date2').value = '';
      break;
    case 'прошлый год':
      var last_year_begin = new Date(today_year-1, 0, 1);
      var last_year_end = new Date(today_year-1, 11, 31);
      $('f_date1').value = dateToString(last_year_begin);
      $('f_date2').value = dateToString(last_year_end);
      break;
  }
  checkCalender($('f_date1').value , $('f_date2').value, src.selectedIndex);
}

// добавить запрос в url. Имеется случай, когда генирируем содержимое посредством AJAX и соответственно
// url не совподает. Таким образом переносим генерацию ссылки на сторону клиента
function urlAddQuery(query) {
  var loc;
  if ( /(\?)/.test(location.href) )
    loc = location.href + '&' + query;
  else
    loc = location.href + '?' + query;

  return loc;
}

// ----------------------------------------------- Check text -------------------------------------------------


// -------------------- Check e-mail --------------------------
function checkMail(email) {

  var pattern = /^[a-zA-Z0-9_\.-]+@[a-zA-Z0-9_\.-]+?\.[a-zA-Z]{2,6}$/;  //  \w
  return pattern.test(email);
}

// проверяет пустоты в строках; если хоть один символ отличный от пробела - return true
function checkEmpty(text) {

  index = 0;
  while(text.charAt(index) == " " || text.charAt(index) == "\n")
    index++;
  return (text.length != index);
}

//trim for JS
function TrimStr(s) {
  s = s.replace( /^\s+/g, '');
  return s.replace( /\s+$/g, '');
}



// ----------------------------------------------- String functions -------------------------------------------------

// Pad a string to a certain length with another string
function stringPad(str, pad_str, pad_length) {
  var direction = (pad_length >= 0) ? true : false;
  pad_length = Math.abs(pad_length);
  for (var i=0; i<pad_length ; i++)  {
    str = direction ? str + pad_str : pad_str + str;
  }
  return str;
}










// -------------------------------------------- NEW common.js ----------------------------------------------------








// -------------- PopupWin Shadow  class (с элементом close) ----------------
//new PopupWinUni_s( '<div style="padding: 10px;">content</div>',
//                      {width: '250', height: '100',  window_bcolor: '#d6d6d6', content_bcolor: '#e6e6e6', head_title: 'head', head_image: 'img_src'}  );
function PopupWinUni_s(dest, property) {
  if (typeof(property) == 'undefined') {
    var property = {};
  }
  if (typeof(dest) == 'undefined') {
    var dest = '';
  }

  var window_bcolor  = property.window_bcolor  ? property.window_bcolor  : '#d6d6d6';
  var content_bcolor = property.content_bcolor ? property.content_bcolor : '#e6e6e6';

  var head_title = property.head_title ? property.head_title : '';
  var head_visible   = property.head_visible !== false   ? '' : 'style="display: none"';
  var head = property.head_image  ? '<img src="'+property.head_image+'" width="16" height="16" alt="" /><span class="head_msg">'+head_title+'</span>'
                                  : '<span class="">'+head_title+'</span>';


  if (typeof PopupWinUni_s.ini == 'undefined') {
    PopupWinUni_s.ini = true;
    PopupWinUni_s.counter = 0;
    PopupWinUni_s.wins = [];
  }


  // можем использовать только private.property так как ед. public.method не может использовать pablic.property из-за event
  if (typeof(dest) != 'object') {
    var wrapper = document.createDocumentFragment();
    var win = document.createElement('div');  win.className = 'popup_win_shadow';
    win.innerHTML =  '<i class="b-popup-tl"></i><i class="b-popup-tr"></i><i class="b-popup-t"></i><i class="b-popup-l"></i>' +
                     '<div class="popup_win_content_wrapper">' +
                        '<div class="popup_drag">' + head + '</div>' +
                        '<div class="popup_win_content">' + dest +  '</div>' +
                     '</div>'  +
                     '<i class="b-popup-r"></i><i class="b-popup-b"></i><i class="b-popup-bl"></i><i class="b-popup-br"></i>';

    if ( typeof(property) != 'object')  {
      var property = {};
    }
    var win_content = getElementsByClassName('popup_win_content', win)[0];


    win_content.style.backgroundColor = content_bcolor;

    var content_wrapper = getElementsByClassName('popup_win_content_wrapper', win)[0];
    content_wrapper.style.backgroundColor = window_bcolor;

    wrapper.appendChild(win);
    document.body.appendChild(wrapper);

    win.style.display = 'block';
    win_content.style.width  = property.width  ? property.width   + 'px' : 'auto';   // IE7 - с auto геморой
    win_content.style.height = property.height ? property.height  + 'px' : win_content.clientHeight < 80 ? '80px' : 'auto';




    // for IE7 (иначе тянет width: 100%)
    if (defineBrowser() == 'IE') {       // IE7  (иначе тянет width: 100%)
      //win.style.display = "block";
      // проблем со scroll не возникает
      // 2+2 padding from parent , 2 border self , -1 / IE еще тот прикол

      win.style.width = win_content.clientWidth + 4 + 2 + 1 + 'px';   // popup_win_content
    }
    dest = win;
    dest.html = true;
  }
  else {
    if (dest.className != 'popup_win_shadow') {
      dest = MakeShadowBox(dest, {});
    }


    // php createShadowPopupWin()
    if (defineBrowser() == 'IE') {       // IE7
      dest.style.display = "block";
      // 2+2 padding from parent , 2 border self
      //alert(dest.getElementsByTagName('div')[2].clientWidth);
      //var cont = getElementsByClassName('popup_win_content',dest);
      //alert(cont[0].clientWidth);

      var win_content  = getElementsByClassName('popup_win_content', dest)[0];
      //dest.style.width = getElementsByClassName('popup_win_content', dest)[0].clientWidth + 4 + 2  + 'px';
      dest.style.width = win_content.clientWidth + 4 + 2  + 'px';

      // scroll-bar 17px
    }
  }

  var close = document.createElement('div');
  close.className = 'popup_img_close';
  document.body.appendChild(close);

  var overlay = document.createElement('div');

  overlay.className = 'overlay';

/*  if (PopupWinUni_s.counter == 1) {
    overlay.className = 'overlay';
  }
  else {
    overlay.className = 'overlay_transparent';   // прозрачные обьекты перекрываются
    //overlay.className = 'overlay';
  }
*/


  document.body.appendChild(overlay);

  overlay.style.zIndex = 100  + PopupWinUni_s.counter * 3;
  dest.style.zIndex    = 101 + PopupWinUni_s.counter * 3;
  close.style.zIndex   = 102 + PopupWinUni_s.counter * 3;

  //var id = PopupWinUni_s.counter;

  this.overlay = overlay;
  this.close = close;
  this.dest = dest;
  this.dragging = false;
  this.drag_target = dest.getElementsByTagName('div')[1];
  this.id = PopupWinUni_s.counter;
  this.property = property;

  PopupWinUni_s.wins[PopupWinUni_s.counter] = this;

  this.show = function() {
    //alert('show');
    dest.style.display = "block";

    var wnd = getWindowSize();

    var win_top  = (wnd.clientHeight > dest.clientHeight) ? (wnd.clientHeight/2 -  dest.clientHeight/2  +  wnd.scrollTop) : 0;
    var win_left = (wnd.clientWidth > dest.clientWidth) ? (wnd.clientWidth/2  - dest.clientWidth/2   +  wnd.scrollLeft) : wnd.clientWidth - dest.clientWidth ;

    //var win_top = (wnd.clientHeight/2 -  dest.clientHeight/2  +  wnd.scrollTop);

    //var win_left = (wnd.clientWidth/2  - dest.clientWidth/2   +  wnd.scrollLeft);





    dest.style.top  = win_top + "px";
    dest.style.left = win_left + "px" ;

    // IE / если overlay backgroundColor: transparent  - он не перекрывает
/*    if ( PopupWinUni_s.counter == 0) {
      overlayShow(overlay, 0.3);
    }
    else {
      overlayShow(overlay, 0);
    }*/

    // базовый overlay (dark)
    if ( PopupWinUni_s.counter == 0) {
      var class_overlay = document.createElement('div');
      class_overlay.className = 'overlay';
      document.body.appendChild(class_overlay);
      overlayShow(class_overlay, 0.3);
      PopupWinUni_s.overlay = class_overlay;
    }

    overlayShow(overlay, 0);

    dest.style.visibility = "visible";

    close.style.display = 'block';

    //alert(win_left + ' ' + dest.clientWidth + ' ' +   dest.scrollWidth);
    close.style.top = dest.html ? win_top + 9 + 2 + "px" : win_top + 9 + 2 + "px";   // 9 - shadow / 2 наш padding
    close.style.left = win_left + dest.clientWidth - close.clientWidth - 2  + "px";   //  2 наш padding
    //alert('show>   i:' + PopupWinUni_s.counter + ' id:' +  this.id + ' c:' + (PopupWinUni_s.counter+1) + ' l:' + PopupWinUni_s.wins.length);
  }

  this.hide = function() {

    Event.stopObserving(_this.close,    'click',    _this.hide);
    Event.stopObserving(window,   'resize',   _this.show);
    Event.stopObserving(window,   'scroll',   _this.show);
    Event.stopObserving(document, 'keypress', _this.check_esc);
    Event.stopObserving(_this.drag_target, 'mousedown',  _this.mousedown);
    Event.stopObserving(_this.drag_target, 'mouseup',    _this.mouseup);
    Event.stopObserving(document,          'mousemove',  _this.mousemove);
    Event.stopObserving(_this.overlay,          'click',  _this.overlay_click);

    document.body.removeChild(overlay);
    document.body.removeChild(close);
    if (dest.html) {
      document.body.removeChild(dest);
    }
    else {
      dest.style.visibility = "hidden";
      dest.style.display = "none";
    }

    --PopupWinUni_s.counter;

    // Делается для
    // 1. Чтобы PopupWinUni_s.counter всегда соответствовал PopupWinUni_s.wins.length. Иначе при создании новых окон,
    //    ссылки на новые могут перетереть старые
    // 2. key:esc / необходимо будет найти верхнее окно для закрытия. Тогда через PopupWinUni_s.counter всегда можно будет его найти
    // вырезаем ссылку на  закрытый элемент
    var start_pos = PopupWinUni_s.wins[_this.id].id;
    PopupWinUni_s.wins.splice(start_pos ,1);
    // сдвигаем массив ссылок на открытые окна чтобы id соответствовал index в PopupWinUni_s.wins
    // чтобы через id найти index в PopupWinUni_s.wins, когда будем вырезать ссылку из массива
    for (var i=0; i < PopupWinUni_s.wins.length ; i++) {
      PopupWinUni_s.wins[i].id = i;
    }


    // удаляем class(base gray) overlay, если больше нет открытых окон
    if ( PopupWinUni_s.counter == 0) {
      document.body.removeChild(PopupWinUni_s.overlay);
    }


    //user function on close popup event
    if (_this.property.onClose) {
      _this.property.onClose();
    }
  }

  this.check_esc = function(event) {

   var event = window.event ? window.event : event;

    // останавливаем обработчик для остальных активных окон / esc закрывает только верхнее окно
    if(event == PopupWinUni_s.esc_event) {
      return;
    }

    //alert(event.type);
    if (event.keyCode == 27) {    //key:esc
      // Закрываем верхнее окно
      PopupWinUni_s.wins[PopupWinUni_s.counter - 1].hide();
      // запоминаем это событие, чтобы остановить выполнение обработчика для остальных активных окон
      PopupWinUni_s.esc_event = event;
      // for onClose user function  (на esc, есть какое-то default-событие в браузере)
      eventPrevent(event);
    }

  }


   this.overlay_click = function()  {
    _this.hide();
  }



  this.mousedown = function(event) {
    _this.dragging = true;
    event = window.event ? window.event : event;
    _this.mouseposX = event.clientX;
    _this.mouseposY = event.clientY;

    if (window.event) {
      _this.popup_oldfunction = document.onselectstart;
      document.onselectstart = new Function("return false;");
    }
    else {
      _this.popup_oldfunction = document.onmousedown;
      document.onmousedown   = new Function("return false;");
    }
  }

  this.mouseup = function() {
    _this.dragging = false

    if (window.event) {
       document.onselectstart = _this.popup_oldfunction;
    }
    else {
       document.onmousedown = _this.popup_oldfunction;
    }
  }

  this.mousemove = function(event) {
    //alert('move');
    if (!_this.dragging) {
      return;
    }
    event = window.event ? window.event : event;
    new_mouseposX = event.clientX;
    new_mouseposY = event.clientY;

     _this.dest.style.left = (_this.dest.offsetLeft + new_mouseposX -_this.mouseposX ) + 'px';
     _this.dest.style.top  = (_this.dest.offsetTop  + new_mouseposY -_this.mouseposY ) + 'px';
     _this.close.style.left = (_this.close.offsetLeft + new_mouseposX -_this.mouseposX ) + 'px';
     _this.close.style.top  = (_this.close.offsetTop   + new_mouseposY -_this.mouseposY ) + 'px';

    _this.mouseposX = new_mouseposX;
    _this.mouseposY = new_mouseposY;
  }

  Event.observe(this.close, 'click', this.hide);

  Event.observe(window, 'resize',   this.show);   // уменьшает скорость
  Event.observe(window, 'scroll',   this.show);   // уменьшает скорость
  Event.observe(document, 'keypress', this.check_esc);   // ??? в IE не работает window - keypress
  Event.observe(this.overlay, 'click', this.overlay_click);

  Event.observe(this.drag_target, 'mousedown',  this.mousedown);
  Event.observe(this.drag_target, 'mouseup',    this.mouseup);
  Event.observe(document,         'mousemove',  this.mousemove);

  // нужен только для Event.stopObserving( not this) , чтобы не замыкать свойства на обьектах
  var  _this = this;

  this.show();

  ++PopupWinUni_s.counter;
}






// -------------------------------- getElementsByClassName -------------------------------------
/*
 * jvlGetClass - JavaScript-функция для выборки DOM-узлов по имени класса
 *   Версия 0.2
 *
 * Copyright (c) 2010 Александр Кузнецов aka Regent(http://vl.vg/)
 *   Подробности: http://vl.vg/18.01.2010/get-elements-by-class-name/
 * Дата создания: 18.01.2010
 */
var getElementsByClassName = (
  function(){
    var d = window.document;
    if( typeof d.getElementsByClassName == 'function' )
      return function( className, node ){
        return ( node || d ).getElementsByClassName( className );
      };
    else if( typeof d.querySelectorAll == 'function' )
      return function( className, node ){
        return ( node || d ).querySelectorAll( '.' + className );
      };
    else
      return function( className, node ){
        if( !className )
          return [];
        var
          // node - родитель - место поиска елементов
          // Если node не передан, то им становится document
          // Берём все DOM-элементы узла
          elements = ( node || document ).getElementsByTagName( '*' ),
          list = [],
          expr = new RegExp( '(^|\\b)' + className + '(\\b|$)' );
        if( elements.length == 0 )
          return elements;
        for( var i = 0, length = elements.length; i < length; i++ )
          if( expr.test( elements[ i ].className ) )
            list[ list.length ] = elements[ i ];
        return list;
      };
  }
)();

function defineBrowser() {
  //alert (navigator.userAgent);
  if (navigator.userAgent.indexOf('MSIE') > -1) return 'IE';
  else if (navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Chrome') == -1 ) return 'FF';
  else if (navigator.userAgent.indexOf('Opera') > -1) return 'Opera';
  else if (navigator.userAgent.indexOf('Chrome') > -1) return 'Chrome';
  else return null;
}

// -------------------------------------------  Window size -----------------------------------------

function getWindowSize() {

  // document.documentElement.clientHeight видимая область
  // document.documentElement.scrollTop (невидимая scroll, то что в данный момент проскроллено)

  var body = document.body;
  var html = document.documentElement;

  var clientHeight = (html && html.clientHeight || body && body.clientHeight || 0);
  var clientWidth = (html && html.clientWidth || body && body.clientWidth || 0);
  var scrollTop = (html && html.scrollTop || body && body.scrollTop || 0);
  var scrollLeft = (html && html.scrollLeft || body && body.scrollLeft || 0);

  return {'clientHeight' : clientHeight , 'clientWidth' : clientWidth , 'scrollTop' : scrollTop , 'scrollLeft' : scrollLeft};
}


//trim for JS
function trim(s) {
  s = s.replace( /^\s+/g, '');
  return s.replace( /\s+$/g, '');
}



function checkJSON(response) {

  var json = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(response.replace(/"(\\.|[^"\\])*"/g, ''))) &&
             trim(response) != ''    &&     eval('(' + response + ')');

  if (!json) {
    showMessage('Server error. Incorrect answer.<br/><br/>' + response + '<br/><br/>' + decodeURIComponent(response), '', 'error')
    return false;
  }

  if (json.status == 'error' ) {
    showMessage(json.data, '', 'error')
    //throw new Error();
    return false;
  }
  return json;
}

function showMessage(message, head, status) {
  // Не плохо было бы сделать класс с инстанциями
  if (typeof(head) == 'undefined' || head == null)  head = '';
  if (typeof(status) == 'undefined' || status == null)  status = '';
  new PopupWinUni_s( message,
     {width: '500', height: '',  window_bcolor: '#d6d6d6', content_bcolor: '#e6e6e6', head_title: head, head_image: '/images/info/' + status + '.png'}  );
}

function RequestErrorMsg(r){
  showMessage("error: "+r.status+"\t"+r.statusText, 'Error: HTTP Request', "error");
}

// clear innerHTML for tables nodes: table, tbody, tr  (td support innerHTML)
function clearContent(node) {
  if (navigator.userAgent.indexOf('MSIE') > -1)
    node.innerText = ''; // IE table elements.innerHTML - readOnly
  else
    node.innerHTML = '';
}


