var base_domain = base_domain || "/";

var browser = {
  opera: /opera/i.test(navigator.userAgent),
  msie: (!this.opera && /msie/i.test(navigator.userAgent)),
  msie6: (!this.opera && /msie 6/i.test(navigator.userAgent)),
  mozilla: /firefox/i.test(navigator.userAgent),
  chrome: /chrome/i.test(navigator.userAgent),
  safari: (!(/chrome/i.test(navigator.userAgent)) && /webkit|safari|khtml/i.test(navigator.userAgent))
}

function getLang(){
  try{
    var args = Array.prototype.slice.call(arguments);
    var key = args.shift();
    if(!key)return '...';
    var val = (window.langpack && window.langpack[key]) || window[key];
    if(!val){
      return key.replace(/_/g, ' ');
    }
    if(isFunction(val)){
      return val.apply(null, args);
    }else{
      return val;
    }
  }catch(e){
    debugLog('lang error:' + e.message);
  }
}
/**
 * DOM
 **/
function ge() {
  var ea;
  for (var i = 0; i < arguments.length; i++) {
    var e = arguments[i];
    if (typeof e == 'string')
      e = document.getElementById(e);
    if (arguments.length == 1)
      return e;
    if (!ea)
      ea = new Array();
    ea.push(e);
  }
  return ea;
}

var _logTimer = (new Date()).getTime();
function debugLog(msg){
  try{ if(ge('debuglog')){
    if(msg===null)msg = '[NULL]';
    else if(msg===undefined)msg = '[UNDEFINED]';
    ge('debuglog').innerHTML += '['+(((new Date()).getTime() - _logTimer)/1000)+'] ' + msg.toString().replace(/</g, '&lt;').replace(/>/g, '&gt;')+"<br/>"; 
  } }catch(e){}
}

function geByClass(searchClass, node, tag) {
  var classElements = new Array();
  if ( node == null )
          node = document;
  if ( tag == null )
          tag = '*';
  if (node.getElementsByClassName) {
    classElements = node.getElementsByClassName(searchClass);
    if (tag != '*') {
      for (i = 0; i < classElements.length; i++) {
        if (classElements.nodeName == tag) 
          classElements.splice(i, 1);
      }
    }
    return classElements;
  }
  var els = node.getElementsByTagName(tag);
  var elsLen = els.length;
  var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
  for (i = 0, j = 0; i < elsLen; i++) {
    if ( pattern.test(els[i].className) ) {
      classElements[j] = els[i];
      j++;
    }
  }
  return classElements;
}

function show(elem) {
  if (arguments.length > 1) {
    for (var i = 0; i < arguments.length; i++) {
      show(arguments[i]);  
    }
    return;
  }
  elem = ge(elem);
  if (!elem) return;
  var old = data(elem, "olddisplay");
  elem.style.display = old || "";
  
  if (getStyle(elem, 'display') == "none" ) {
    if (elem.tagName.toLowerCase() == 'tr' && !browser.msie) {
      elem.style.display = 'table-row';
    } else if (elem.tagName.toLowerCase() == 'table' && !browser.msie) {
      elem.style.display = 'table';
    } else {
      elem.style.display = data(elem, "olddisplay", "block");
    }
  }
}

function hide(elem){
  if (arguments.length > 1) {
    for (var i = 0; i < arguments.length; i++) {
      hide(arguments[i]);  
    }
    return;
  }
  elem = ge(elem);
  if (!elem) return;
  if (getStyle(elem, 'display') != "none")
    data(elem, "olddisplay", elem.style.display);
  elem.style.display = "none";
}
function isVisible(elem) {
 elem = ge(elem);
 return getStyle(elem, 'display') != 'none' && getStyle(elem, 'visibility') != 'hidden';
}
function toggle(elem) {
  if (isVisible(elem)) {
    hide(elem);
  } else {
    show(elem);
  }
}
window.shide = toggle;

function getXY(obj) {
 if (!obj || obj == undefined) return;
 var left = 0, top = 0;
 if (obj.offsetParent) {
  do {
   left += obj.offsetLeft;
   top += obj.offsetTop;
  } while (obj = obj.offsetParent);
 }
 return [left,top];
}




/**
 *  Useful utils
 */

Function.prototype.bind = function(object) {
  var __method = this;
  return function() {
    return __method.apply(object, arguments);
  }
};
function isFunction(obj) {return Object.prototype.toString.call(obj) === "[object Function]"; }
function isArray(obj) { return Object.prototype.toString.call(obj) === "[object Array]"; }
function now() { return +new Date; }
function trim(text) { return (text || "").replace(/^\s+|\s+$/g, ""); }
function stripHTML(text) { return text.replace(/<(?:.|\s)*?>/g, ""); }
function escapeRE(s) { return s.replace(/[.*+?^${}()|[\]\/\\]/g, '\\$0'); }

/**
 *  Arrays, objects
 **/

function each(object, callback) {
  var name, i = 0, length = object.length;

  if ( length === undefined ) {
    for ( name in object )
      if ( callback.call( object[ name ], name, object[ name ] ) === false )
        break;
  } else
    for ( var value = object[0];
      i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}

  return object;
};
function indexOf(arr, value, from) {
  from = (from == null) ? 0 : from; 
  var m = arr.length;
  for(var i = from; i < m; i++) 
    if (arr[i] == value)
       return i;
   return -1;
}

function clone(obj) {
  var newObj = {};
  for (var i in obj) {
    newObj[i] = obj[i];
  }
  return newObj;
}


// Extending object by another
function extend() {
  // copy reference to target object
  var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;

  // Handle a deep copy situation
  if (typeof target === "boolean") {
    deep = target;
    target = arguments[1] || {};
    // skip the boolean and the target
    i = 2;
  }

  // Handle case when target is a string or something (possible in deep copy)
  if (typeof target !== "object" && !isFunction(target))
    target = {};

  // return target object if only one argument is passed
  if (length == i) {
    return target;
  }

  for (; i < length; i++)
    // Only deal with non-null/undefined values
    if ((options = arguments[i]) != null)
      // Extend the base object
      for (var name in options) {
        var src = target[name], copy = options[name];

        // Prevent never-ending loop
        if (target === copy)
          continue;

        // Recurse if we're merging object values
        if (deep && copy && typeof copy === "object" && !copy.nodeType)
          target[name] = extend(deep, 
            // Never move original objects, clone them
            src || (copy.length != null ? [] : { })
          , copy);

        // Don't bring in undefined values
        else if (copy !== undefined)
          target[name] = copy;
      }

  // Return the modified object
  return target;
}


/**
 * CSS classes
 **/

function hasClass(obj, name) {
  obj=ge(obj);
  return obj && (new RegExp('(\\s|^)' + name + '(\\s|$)')).test(obj.className);
}
 
function addClass(obj, name) {
  obj=ge(obj);
  if (obj && !hasClass(obj, name)) obj.className = (obj.className ? obj.className + ' ' : '') + name;
}

function removeClass(obj, name) {
  obj=ge(obj);
  if (obj && hasClass(obj, name)) obj.className = obj.className.replace((new RegExp('(\\s|^)' + name + '(\\s|$)')), ' ');
}

// Get computed style
function getStyle(elem, name, force) {  
  if (force === undefined) force = true;
  if (!force) {
    return elem.style[name];
  }
  if (name == "width" || name == "height") {
    return getSize(elem, true)[({'width':0, 'height':1})[name]] + 'px';
  }
  var ret, defaultView = document.defaultView || window;
  if (defaultView.getComputedStyle) {
    name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
    var computedStyle = defaultView.getComputedStyle( elem, null );
      if (computedStyle)
        ret = computedStyle.getPropertyValue(name);
  } else if (elem.currentStyle) {
    if (name == 'opacity' && browser.msie) {
      var filter = elem.currentStyle['filter'];
      return filter && filter.indexOf("opacity=") >= 0 ?
        (parseFloat(filter.match(/opacity=([^)]*)/)[1] ) / 100) + '' : '1';
    }
    var camelCase = name.replace(/\-(\w)/g, function(all, letter){
      return letter.toUpperCase();
    });
    ret = elem.currentStyle[name] || elem.currentStyle[camelCase];
    // If we're not dealing with a regular pixel number
    // but a number that has a weird ending, we need to convert it to pixels
    if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
      // Remember the original values
      var left = style.left, rsLeft = elem.runtimeStyle.left;

      // Put in the new values to get a computed value out
      elem.runtimeStyle.left = elem.currentStyle.left;
      style.left = ret || 0;
      ret = style.pixelLeft + "px";

      // Revert the changed values
      style.left = left;
      elem.runtimeStyle.left = rsLeft;
    }
  }
  return ret;
}

function setStyle(elem, name, value){
  elem = ge(elem);
  if (name == 'opacity'){
    if (browser.msie) {elem.style.filter = "alpha(opacity=" + value*100 + ")"; elem.style.zoom = 1; };
    elem.style.opacity = value;
  } else elem.style[name] = typeof(value) == 'number' && !(/z-?index|font-?weight|opacity|zoom|line-?height/i).test(name) ? value + 'px': value;
}

/**
 * Store data connected to element
 **/

var expand = "VK" + now(), vk_uuid = 0, vk_cache = {};

// Get or set element data
function data(elem, name, data) {
  var id = elem[ expand ], undefined;
  if ( !id )
    id = elem[ expand ] = ++vk_uuid;

  if (name && !vk_cache[id])
    vk_cache[id] = {};

  if (data !== undefined)
    vk_cache[id][name] = data;

  return name ?
    vk_cache[id][name] :
    id;
}

function removeData(elem, name) {
  var id = elem[expand];
  if (name) {
    if (vk_cache[id]) {
      delete vk_cache[id][name];
      name = "";
      for (name in vk_cache[id])
        break;

      if (!name)
        removeData(elem);
    }
  } else {
    try {
      delete elem[expand];
    } catch(e){ // fix for IE
      if (elem.removeAttribute)
        elem.removeAttribute(expand);
    }
    delete vk_cache[id];
  }
}


  
/**
 * Events
 **/
var KEY = window.KEY = {
  LEFT: 37,
   UP: 38,
   RIGHT: 39,
   DOWN: 40,
   DEL: 8,
   TAB: 9,
   RETURN: 13,
   ESC: 27,
   PAGEUP: 33,
   PAGEDOWN: 34,
   SPACE: 32
 };
 
function addEvent(elem, types, handler) {
  elem = ge(elem);
  if (!elem || elem.nodeType == 3 || elem.nodeType == 8 )
    return;
  
  // For whatever reason, IE has trouble passing the window object
  // around, causing it to be cloned in the process
  if (elem.setInterval && elem != window)
    elem = window;
    
  var events = data(elem, "events") || data(elem, "events", []),    
      handle = data(elem, "handle") || data(elem, "handle", function(){
        _eventHandle.apply(arguments.callee.elem, arguments);
      });
  // Add elem as a property of the handle function
  // This is to prevent a memory leak with non-native
  // event in IE.
  handle.elem = elem;
  each(types.split(/\s+/), function(index, type) {
    var handlers = events[type];
    if (!handlers) {
      handlers = events[type] = new Array();
      
      if (elem.addEventListener) 
        elem.addEventListener(type, handle, false);
      else if (elem.attachEvent) 
        elem.attachEvent('on' + type, handle);
    }
    handlers.push(handler);
  });
  
  elem = null;
}



function cancelEvent(event) {
  var e = event.originalEvent || event;
  if (e.preventDefault)
      e.preventDefault();
  if (e.stopPropagation) 
      e.stopPropagation(); 
  e.cancelBubble = true;
  e.returnValue = false;
  return false;
}

function _eventHandle(event) {
  event = event || window.event;
  
  var originalEvent = event;
  event = clone(originalEvent);
  event.originalEvent = originalEvent;

  if (!event.target)
    event.target = event.srcElement || document; 

  // check if target is a textnode (safari)
  if ( event.target.nodeType == 3 )
    event.target = event.target.parentNode;

  if (!event.relatedTarget && event.fromElement)
    event.relatedTarget = event.fromElement == event.target 
    
  if ( event.pageX == null && event.clientX != null ) {
    var doc = document.documentElement, body = document.body;
    event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
    event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
  }
  
  if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
    event.which = event.charCode || event.keyCode;

  // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
  if ( !event.metaKey && event.ctrlKey )
    event.metaKey = event.ctrlKey;
    
  // Add which for click: 1 == left; 2 == middle; 3 == right
  // Note: button is not normalized, so don't use it
  if ( !event.which && event.button )
    event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));

  var handlers = data(this, "events");
  if (!handlers || typeof(event.type) != 'string' || !handlers[event.type] || !handlers[event.type].length) { 
    return;
  }
  try {
  //fixed: handlers[event.type] = undefined
  for (var i = 0; i < (handlers[event.type] || []).length; i++) {
    if (event.type == 'mouseover' || event.type == 'mouseout') {
      var parent = event.relatedElement;
      // Traverse up the tree
      while ( parent && parent != this )
        try { parent = parent.parentNode; }
        catch(e) { parent = this; }
      if (parent == this) {
        continue
      }
    }
    var ret = handlers[event.type][i].apply(this, arguments);
    if (ret === false) {
      cancelEvent(event);
    }
  }
  } catch (e) {
    debugLog(event.target.id+"."+event.type+": "+e.message);
  }
}

// Prevent memory leaks in IE
// And prevent errors on refresh with events like mouseover in other browsers
// Window isn't included so as not to unbind existing unload events
addEvent(window, "unload", function(){ 
  for (var id in vk_cache)
    if (vk_cache[id].handle && vk_cache[id].handle.elem != window)
      removeEvent(vk_cache[id].handle.elem);
});






function nameTip(obj) {
 if (parseInt(qCur) || obj.value.length || qd) {return;}
 show('qfriends');
 ge('qfriends').innerHTML = "<div style='border-top: 1px solid #C6D0D9; padding: 4px 18px; background-color: #FAFAFA;'>Здесь Вы можете ввести имя и фамилию</div>";
}
function strrev( string ){
    var ret = '', i = 0;

    string += '';
    for ( i = string.length-1; i >= 0; i-- ){
       ret += string.charAt(i);
    }

    return ret;
}
function wordwrap( str, int_width, str_break, cut ) {
    var m = ((arguments.length >= 2) ? arguments[1] : 75   );
    var b = ((arguments.length >= 3) ? arguments[2] : "\n" );
    var c = ((arguments.length >= 4) ? arguments[3] : false);

    var i, j, l, s, r;

    str += '';

    if (m < 1) {
        return str;
    }

    for (i = -1, l = (r = str.split(/\r\n|\n|\r/)).length; ++i < l; r[i] += s) {
        for(s = r[i], r[i] = ""; s.length > m; r[i] += s.slice(0, j) + ((s = s.slice(j)).length ? b : "")){
            j = c == 2 || (j = s.slice(0, m + 1).match(/\S*(\s)?$/))[1] ? m : j.input.length - j[0].length || c == 1 && m || j.input.length + (j = s.slice(m).match(/^\S*/)).input.length;
        }
    }
    
    return r.join("\n");
}
