var linkedCSS = new Array(), linkedJS = new Array();
var isLoc = location.href.indexOf('estateline.loc') != -1;
var randomizer = isLoc ? '?r=' + Math.random() : '';

var staticServer = (function() {
	var staticServer = 'http://static.estateline.ru/';
	
	var ssLen = staticServer.length;
	if(staticServer[ssLen-1] == '/') staticServer = staticServer.substr(0, ssLen-1);
	return staticServer;
})();

$.extend({
  staticUrl : function(filename)
  {
	if(isLoc || filename.indexOf('/manager/')===0) return filename;
	if(typeof filename == 'undefined' || filename.indexOf(staticServer)!==-1) return staticServer;
	return staticServer + (filename.indexOf('/')!==0 ? '/' : '') + filename;
  },
  headCSS : function(filename)
  {
	if (jQuery.inArray(filename, linkedCSS) == -1) {
		$('head').append('<link href="' +
		jQuery.staticUrl(filename) + randomizer +
		'" rel="stylesheet" media="all" />');
		linkedCSS = linkedCSS.concat([filename]);
    }
  },
  headJS : function(filename, callback)
  {
	if (jQuery.inArray(filename, linkedJS) == -1) {		
		var url = jQuery.staticUrl(filename) + randomizer;
		jQuery.ajax({
			url: url,
			dataType: "script",
			cache: true,
			success: function() {
				if(typeof callback !== 'undefined') callback();
			}
		});
		
		/*jQuery.getScript(url, function() { 
			if(typeof callback !== 'undefined') callback(); 
		});*/
		linkedJS = linkedJS.concat([filename]);
    }
  },
  uid : function()
  {
    var ss = [], tok = [8, 4, 4, 4, 12];
    for(var i = 0; i < 5; i++) {
      var s = '';
      for (var j = 0; j < tok[i]; j++) {
        var r = parseInt(Math.random() * 16);
        r = r < 10 ? r : (
          r == 10 ? 'A' : (
          r == 11 ? 'B' : (
          r == 12 ? 'C' : (
          r == 13 ? 'D' : (
          r == 14 ? 'E' : 'F')))));
        s+= r;
      }
      ss = ss.concat([s]);
    }
    return ss.join('-').toUpperCase();
  },
  width : function()
  {
    return window.innerWidth != null ? window.innerWidth : document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;
  },
  height : function()
  {
    return window.innerHeight != null? window.innerHeight: document.documentElement && document.documentElement.clientHeight ? document.documentElement.clientHeight:document.body != null? document.body.clientHeight:null;
  },
  scrollHeight : function()
  {
    try {
      var h = window.pageYOffset ||
            document.body.scrollTop ||
            document.documentElement.scrollTop;
    } catch (e) {
      var h = 0;
    }
    return h ? h : 0;
  },
  scrollWidth : function()
  {
     var w = window.pageXOffset ||
             document.body.scrollLeft ||
             document.documentElement.scrollLeft;

     return w ? w : 0;
  },
  /**
   * Переводит строку в число, например 10'000,50 -> 10000.5
   * @param {String} string
   * @return {Number}
   */
  string2number : function(string)
  {
    string = string.toString();
    while (string.indexOf(' ') > -1) string = string.replace(/ /, '');
    while (string.indexOf('\'') > -1) string = string.replace(/'/, '');
    while (string.indexOf(',') > -1) string = string.replace(/,/, '.');
    return string * 1;
  },
  /**
   * Format a number with grouped thousands
   *
   * @param {Number} number The number being formatted
   * @param {Number} decimals Sets the number of decimal points
   * @param {String} dec_point Sets the separator for the decimal point
   * @param {String} thousands_sep Sets the thousands separator
   */
  number_format : function number_format(number, decimals, dec_point, thousands_sep)
  {
    var exponent = "";
    var numberstr = number.toString ();
    var eindex = numberstr.indexOf ("e");
    var i, z;
    if(eindex > -1){
      exponent = numberstr.substring (eindex);
      number = parseFloat (numberstr.substring (0, eindex));
    }

    if(decimals != null){
      var temp = Math.pow (10, decimals);
      number = Math.round (number * temp) / temp;
    }
    var sign = number < 0 ? "-" : "";
    var integer = (number > 0 ?
        Math.floor (number) : Math.abs (Math.ceil (number))).toString ();

    var fractional = number.toString ().substring (integer.length + sign.length);
    dec_point = dec_point != null ? dec_point : ".";
    fractional = decimals != null && decimals > 0 || fractional.length > 1 ? (dec_point + fractional.substring (1)) : "";
    if(decimals != null && decimals > 0){
      for(i = fractional.length - 1, z = decimals; i < z; ++i)
        fractional += "0";
    }

    thousands_sep = (thousands_sep != dec_point || fractional.length == 0) ?
                    thousands_sep : null;
    if(thousands_sep != null && thousands_sep != ""){
    for (i = integer.length - 3; i > 0; i -= 3)
     integer = integer.substring (0 , i) + thousands_sep + integer.substring (i);
    }
    return sign + integer + fractional + exponent;
  }
})


$.fn.extend({
  /**
   * Синхронизирует значения полей формы. При изменении одного, меняется другое и наоборот
   * @param {Object} elem2
   */
  syncWith : function(elem2)
  {
    var elem1 = $(this);
    $(elem1).change(function(){
      $(elem2).val($(elem1).val());
    });
    $(elem2).change(function(){
      $(elem1).val($(elem2).val());
    });
  },
  refresh : function()
  {
    if ($(this).length) $(this).attr('src', $(this).attr('src').toString().split('?')[0] + '?r=' + Math.random());
    return false;
  },
  centrize : function(onresize, beforeResize)
  {

    onresize = onresize || false;
    var T = this;

    var setToCenter = function(elem, speed) {
//      ////console.info('Centrize %o', $(elem).get(0));

      var pos = $(elem).css('position');

      if (pos == 'absolute') {
        $(elem).animate({
          left: (($(window).width()  - $(elem).width())  / 2) + 'px',
          top : (($(window).height() - $(elem).height()) / 2 + $.scrollHeight()) + 'px'
        }, speed);
      } else {
        if ($.browser.opera) {
          $(elem).css({
            left: (($(window).width()  - $(elem).width())  / 2) + 'px',
            top : ((window.innerHeight - $(elem).height()) / 2 ) + 'px'
          });
        } else {
          $(elem).css({
            left: (($(window).width()  - $(elem).width())  / 2) + 'px',
            top : (($(window).height() - $(elem).height()) / 2 ) + 'px'
          });
        }
      }
    }

    setToCenter($(T), 0);

    if (onresize) {
      $(window).resize(function(){
        if (beforeResize) beforeResize();
        setToCenter($(T), 'fast');
      }).scroll(function(){
        if (beforeResize) beforeResize();
        setToCenter($(T), 0);
      });
    }
  },
  top : function(val)
  {
    if (val == undefined) {
      return parseInt($(this).css('top'));
    } else {
      val = val || 0;
      $(this).css('top', parseInt(val) + 'px');
      return $(this);
    }
  },
  left : function(val)
  {
    if (val == undefined) {
      return parseInt($(this).css('left'));
    } else {
      val = val || 0;
      $(this).css('left', parseInt(val) + 'px');
      return $(this);
    }
  },
  autocomplete : function(url, parameter, data, onComplete)
  {
    if (!onComplete) {
      onComplete = data || function(){};
      data = {};
    }
    if (!data) {
      data = {};
    }
    data[parameter] = $(this).val();
    jQuery.getJSON(url, data, onComplete);
  },
  geoSuggest : function(id_input, onselect, suggest_url)
  {
    if((typeof(suggest_url)=="undefined")){
		suggest_url='/json.geo.search';
	}
	var sgst = $(this);
    var sIndex = -1;
    var requesting = false;

    if (id_input == 'position') {
      var list = onselect.list;
      var sgst = onselect.sgst;

      $(sgst).parent().css('position', 'relative');
      $(list).css('position', 'absolute');
      var h = 0;
      if(!window.innerHeight) {
        if(!(document.documentElement.clientHeight == 0)) h = document.documentElement.clientHeight;
        else h = document.body.clientHeight;
      } else h = window.innerHeight;
      h = h / 2;
      $(list).css('height', h + 'px');
      $(list).css('top', $(sgst).outerHeight() + 'px');
      $(list).css('width', ($(sgst).outerWidth()) + 'px');
      if ($(sgst).parent().find('strong').length) {
        $(list).css('left', ($(sgst).parent().find('strong').outerWidth() + 23) + 'px');
      } else {
        $(list).css('left', '0px');
      }

//      if (list.css('position') == 'absolute') {
//        var top = sgst.offset().top + sgst.outerHeight();
//        var h = window.innerHeight - top + $.scrollHeight();
//      } else {
//        var top = (sgst.offset().top + sgst.outerHeight() - $.scrollHeight());
//        var h = window.innerHeight - top;
//      }
//
//      console.group();
//      ////console.info(list.css('position'));
//      ////console.info('sgst.outerWidth()', sgst.outerWidth());
//      ////console.info('sgst.outerHeight()', sgst.outerHeight());
//      ////console.info('sgst.offset().top', sgst.offset().top);
//      ////console.info('$.scrollHeight()', $.scrollHeight());
//      ////console.info('sgst.offset().left', sgst.offset().left);
//      ////console.info('window.innerHeight', window.innerHeight);
//      ////console.info('top', top);
//      console.groupEnd();
//
//      h = h > 400 ? 400 : h;
//      list.css('height', h + 'px');
//      list.css('width', (sgst.outerWidth()) + 'px');
//      list.css('top', top + 'px');
//      list.css('left', sgst.offset().left + 'px');

      return;
    }

    if (id_input == 'listJSON') {
      var json = onselect.json;
      var list = onselect.list;

      var g = sgst.val();
      var rex = new RegExp(g, 'i');
      var l = g.length;

      $.each(json.data, function(i, item){
        var name = item.name;
        var lname = name.toLowerCase();
        var lrex = new RegExp(g.toLowerCase(), 'i');
        var s = lname.search(lrex);

        if (s > -1) name = name.substr(0, s) + '<em>' + name.substr(s, l) + '</em>' + name.substr(s + l);

        list.append('<li><a href="' + item.id + '" title="' + item.name + '">' +
            '<i>' + name + '</i>' +
            (item["parent"].length ? '<small>' + item["parent"].join(',</small><small>') + '</small>' : '') +
            '</a></li>');
      });
      if (json.next) {
        list.append('<li><a href="more/' + json.next + '" class="more"><i>Далее&hellip;</i>' +
            '<small>Показаны не все совпадения. Уточните запрос или нажмите Далее</small></a></li>');
      }
      if (list.height() > 400) list.height('400px');
      list.find('li').hover(function(){
        list.find('li').removeClass('selected');
        $(this).addClass('selected');
      });
      list.find('li:first').css('border', 'none');
      sgst.removeAttr('disabled');
      sgst.focus();
      return;
    }

    $('.suggest').remove();

    $.headCSS('/manager/css/suggest.css');
    /* уникальный идентификатор */
    var id = $.uid();
    $(sgst).after('<ul id="' + id + '" class="suggest" style="display:none;"></ul>');
    var list = $('#' + id);
    sgst.attr('autocomplete', 'off');

    sgst.parents('#popup-window').click(function(){
      list.hide();
    });

    $(window).resize(function(){
      sgst.geoSuggest('position', {list:list, sgst:sgst});
      window.setTimeout(function(){sgst.geoSuggest('position', {list:list, sgst:sgst})}, 10);
    }).scroll(function(){
      sgst.geoSuggest('position', {list:list, sgst:sgst});
    });

    if ($(id_input).val()) {
      /* есть исходное значение, получим данные для него */
      $.getJSON(suggest_url+'?id=' + $(id_input).val(), function(json){
        ////console.info(json);
        sgst.val(json.name);
        if (!$(sgst).parent().children('.current').length) {
          $(sgst).parent().append('<div class="current"></div>');
          $(sgst).parent().children('.current').empty();
          var smalls = new Array();
          var title = '';
          $.each(json.parent, function(i, item){
            smalls[i] = item;
            if (i == json.parent.length - 1) {
              $(sgst).parent().children('.current').append('<small>' + smalls.join(',</small><small>') + '</small>');
              $(sgst).attr('title', smalls.join(', '));
            }
          });
        }
      });
    }

    list.find('li a').live('click', function(){
      if ($(this).hasClass('more')) {
        /* докачка следующей страницы */
        var p = $(this).attr('href').split('/').pop();
        sgst.attr('disabled', 'disabled');
        var more = $(this).parent();
        $(more).addClass('loading');
        sIndex = list.find('li').index($(more));
        sgst.autocomplete(suggest_url, 'g', {p : p}, function(json){
          sgst.geoSuggest('listJSON', {json : json, list : list});
          $(more).remove();
          var sItem = $(list.find('li').get(sIndex));
          sItem.addClass('selected');
          sItem.find('a').focus();
          sgst.focus();
        });
      } else {
        if (onselect) {
          onselect($(this));
        }
        list.hide();
      }
      return false;
    });

    if (!parseInt($(id_input).val())) {
      sgst.addClass('invalid');
      sgst.removeClass('valid');
    } else {
      sgst.addClass('valid');
      sgst.removeClass('invalid');
    }

    sgst.keydown(function(ev){
      if (ev.keyCode == 13) { /* enter */
        $('#' + id + ' li.selected a').click();
        return false;
      }
      if (ev.keyCode == 27) { /* escape */
        list.hide();
        return false;
      }
    })

    sgst.keyup(function(ev) {

      //////console.info(ev.keyCode);

	  var key = ev.which;
      if (key == 40 || key == 38 || (key >= 33 && key <= 36) || key == 27) { /* down || up || home-end-pgup-pgdn*/
        sIndex = list.find('li').index(list.find('li.selected'));

        list.find('li.selected').removeClass('selected');

        if (key == 40) { /* down */
          sIndex++;
          if (sIndex > list.find('li').size() - 1) sIndex = 0;
        }
        if (key == 38) { /* up */
          sIndex--;
          if (sIndex < 0) sIndex = list.find('li').size() - 1;
        }
        if (key == 33) { /* pgup */
          sIndex-= 10;
          if (sIndex < 0) sIndex = 0;
        }
        if (key == 34) { /* pgdn */
          sIndex+= 10;
          if (sIndex > list.find('li').size() - 1) sIndex = list.find('li').size() - 1;
        }
        if (key == 35) { /* end */
          sIndex = list.find('li').size() - 1;
        }
        if (key == 36) { /* home */
          sIndex = 0;
        }

        if (key == 27) { /* esc */
          list.hide();
          return;
        }

        var sItem = $(list.find('li').get(sIndex));
        sItem.addClass('selected');
        sItem.find('a').focus();
        sgst.focus();
        return;
      }
	  var nono = [27,20,16,17,18,13,33,34,35,36,45,37,38,39,40];
      /*if (key == 32 || key == 59   ||
          key == 46 || key == 8 || key == 109 ||
         (key >= 48 && key <= 57)  ||
         (key >= 65 && key <= 90)  ||
         (key >= 96 && key <= 105) ||
          key == 188 || key == 190 || key == 192 ||
          key == 219 || key == 221 || key == 222) {
*/		
		if(-1 == jQuery.inArray(key,nono)){ 
		sgst.addClass('invalid');
        sgst.removeClass('valid');
        $(id_input).val(0);
        $(sgst).parent().children('.current').empty();

        var value = sgst.val();
        if (value.length >= 3) setTimeout(function(){
          /* Ждем секунду и если значение в поле не изменилось - производим поиск */
          if (value == sgst.val() && sgst.val() && !requesting) {
            requesting = true;
			
            sgst.after('<img class="' + id + ' ajax-loader" src="/manager/images/ajax-select-loader.gif" alt="Загрузка...">');
            sgst.attr('disabled', 'disabled');
            sgst.autocomplete(suggest_url, 'g', {}, function(json){
              sIndex = -1;
              ////console.info(json);
              sgst.geoSuggest('position', {list:list, sgst:sgst});

//              list.css('height', 'auto');
//              list.css('width', (sgst.outerWidth() - 2) + 'px');
//              list.css('top', sgst.offset().top + sgst.outerHeight() + 'px');
//              list.css('left', sgst.offset().left + 'px');
              list.empty();

              sgst.geoSuggest('listJSON', {json : json, list : list});

              $('.' + id).remove(); // ajax-indicator
              if (json.data.length) {
                list.show();
              } else {
                list.hide();
              }
              requesting = false;
            });
          } else {
            value = sgst.val();
          }
        }, 500);
      }
    });
  }
})


var geoSuggestPrepare = function(PopupFilter, popup, activator, uri, suggest_uri, suggest_label)
{
  if(typeof(suggest_uri) == "undefined"){
	  suggest_uri = "/json.geo.search";
  }
  if(typeof(suggest_label) == "undefined"){
	  suggest_label = "Регион";
  }
  var html = '<form class="geo-filter geo-suggest" method="post" action="">' +
      '<input type="hidden" name="geo_id_suggest">' +
      '<div class="fLine fTop"><img height="7" width="7" alt="" class="cL" src="'+jQuery.staticUrl('/siteimg/filter/ftl.gif')+'"/><img height="7" width="7" alt="" class="cR" src="'+jQuery.staticUrl('/siteimg/filter/ftr.gif')+'"/></div>' +
      '<div class="fContent"><strong>' + suggest_label + '</strong>' +
      '<input name="geo_suggest">' +
      '</div>' +
      '<div class="fLine fBottom"><img height="7" width="7" alt="" class="cL" src="'+jQuery.staticUrl('/siteimg/filter/fbl.gif')+'"/><img height="7" width="7" alt="" class="cR" src="'+jQuery.staticUrl('/siteimg/filter/fbr.gif')+'"/></div>' +
      '</form>';

  $(popup).before(html);
  var suggest = $("input[name='geo_suggest']");
  var suggest_id = $("input[name='geo_id_suggest']");
  var column = 1;
  if(suggest_label.length>6){
	$(suggest).css("width","320px");
  }
  var insertNode = function(id, name, title)
  {
    $(popup).find('.column-' + column).prepend('' +
        '<li class="item-' + id + ' selected">' +
        '<a href="' + (uri + id) + '/" title="' + title + '">' + name + '</a></li>');
    column = column < 3 ? column + 1 : 1;
    PopupFilter.logic($(popup).find('.item-' + id));
  }

  $(activator).find('input').each(function(){
    var id = $(this).val();
    if(id && !$(popup).find('.item-' + id).length) {
      $.getJSON(suggest_uri, {id : id}, function(json){
        insertNode(id, json.name, json.parent.length ? json.parent.join(', ') : '');
      });
    }
  });

  $.headCSS('/css/style-suggest.css');

  $(suggest).geoSuggest($(suggest_id), function(item){
    $(suggest).val('');
    var id = $(item).attr('href').split('/').pop();

    if (!PopupFilter.multi) $('#' + PopupFilter.id + ' li.selected').removeClass('selected');

    if ($(popup).find('.item-' + id).length) {
      $(popup).find('.item-' + id).addClass('selected');
    } else {
      var name = $(item).attr('title');
      var title = [];
      $.each($(item).find('small'), function(i, item){
        title = title.concat([$(item).text()]);
      });
      insertNode(id, $(item).attr('title'), title.join(' '));
    }
  }, suggest_uri);
}

$.fn.extend({
  /* Отправлялка формы */
  sendForm : function()
  {
    $(this).find('.submit').attr('disabled', 'disabled');
    if ($(this).validateForm()) $(this).submit();
    $(this).find('.submit').removeAttr('disabled');
    return false;
  },
  /* Проверялка формы */
  validateForm : function()
  {
    //console.group('validateForm(%o)', $(this));
    var valid = true;

    $(this).find('cite.error').remove();
    $(this).find('.error').removeClass('error');

    var elems = $(this).find('.required input, .required textarea, .required select');
    ////console.info('Required', elems);

    $.each(elems, function(i, item){
      if (!$(item).val() ||
          ($(item).val() == '0' && $(item).get(0).tagName == 'SELECT') ||
          ($(item).val() == '0' && $(item).attr('type') == 'hidden') ||
          (!$(item).attr('checked') && $(item).attr('type') == 'checkbox')) {
        valid = false;
        var dd = $(item).parents('dd, .dd');
        $(item).addClass('error');
        if (!dd.find('cite.error').length) {
          if ($(item).attr('type') == 'checkbox') {
            dd.prepend('<cite class="error">Для продолжения вы должны отметить это поле</cite>')
          } else {
            dd.prepend('<cite class="error">Поле не заполнено</cite>')
          }
        }

        if (dd.hasClass('fSelector')) {
          dd.find('.fSelect, .fSelected').addClass('error');
        }
      }
    });

    elems = $(this).find('.e-mail input');
    ////console.info('E-mail', elems);

    $.each(elems, function(i, item){
      if (!$(item).hasClass('error')) { /* Две ошибки рядом - это перебор */
        var test = $(item).val().search(/^[\w][\w\.-]*[\w]@[\w][\w\.-]*[\w]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/);
        if (test == -1) {
          valid = false;
          var dd = $(item).parents('dd, .dd');
          $(item).addClass('error');
          if (!dd.find('cite.error').length) dd.prepend('<cite class="error">Введен неверный адрес e-mail</cite>')
        }
      }
    });

    elems = $(this).find("dd input[type='password']");
    ////console.info('Passwords', elems);

    $.each(elems, function(i, item){
      if (!$(item).hasClass('error')) { /* Две ошибки рядом - это перебор */
        if ($(item).val() && $(item).val().search(/[^a-zA-Z0-9.-]/) > -1) {
          valid = false;
          var dd = $(item).parents('dd, .dd');
          $(item).addClass('error');
          if (!dd.find('cite.error').length) dd.prepend('<cite class="error">В пароле запрещены символы кроме букв латинского алфавита, цифр, точки и дефиса</cite>')
        }
      }
    });

    elems = $(this).find('.min-lenght input, .min-lenght textarea');
    ////console.info('Content Min-Lenght', elems);

    $.each(elems, function(i, item){
      if (!$(item).hasClass('error')) { /* Две ошибки рядом - это перебор */
        var len = parseInt($(item).attr('lang'));
        if (len && $(item).val().length < len) {
          valid = false;
          var dd = $(item).parents('dd, .dd');
          $(item).addClass('error');
          if (!dd.find('cite.error').length) dd.prepend('<cite class="error">Содержимое поля слишком мало. Требуется не менее ' + len + ' символов</cite>')
        }
      }
    });

    elems = $(this).find('.max-lenght input, .max-lenght textarea');
    ////console.info('Content Max-Lenght', elems);

    $.each(elems, function(i, item){
      if (!$(item).hasClass('error')) { /* Две ошибки рядом - это перебор */
        var len = parseInt($(item).attr('lang'));
        if (len && $(item).val().length > len) {
          valid = false;
          var dd = $(item).parents('dd, .dd');
          $(item).addClass('error');
          if (!dd.find('cite.error').length) dd.prepend('<cite class="error">Содержимое поля слишком велико. Требуется не более ' + len + ' символов</cite>')
        }
      }
    });


    /* Теперь, если вдруг сообщение об ошибке спряталось - покажем его */
    //console.warn($('cite.error').parents(':hidden'));
    $('cite.error').parents(':hidden').show();

    //console.groupEnd();
    /* Встанем на первую ошибку */
    if ($('cite.error:visible').length) $('cite.error:visible').scrollToIf();
    return valid;
  },
  /**
   * Перематывает страницу к элементу
   */
  scrollTo : function()
  {
    var eh = $(this).offset().top;
    window.scrollTo(0, eh);
  },
  /**
   * Перематывает страницу к элементу, если элемент вне viewpoint
   */
  scrollToIf : function()
  {
    var eh = $(this).offset().top;
    //alert($.scrollHeight() +'>' + eh + ' || ' + ($(window).height() + $.scrollHeight() - 20) + '<' + eh);
    if ($.scrollHeight() > eh) window.scrollTo(0, eh);
    if (($(window).height() + $.scrollHeight() - 20) < eh) window.scrollTo(0, eh);
  }

});
