// ------------------------------------------------------------------
// helper functions
// ------------------------------------------------------------------
// returns maximal or minimal of two values
function max( val1, val2 )
{
  return val1 > val2 ? val1 : val2;
}
function min( val1, val2 )
{
  return val1 < val2 ? val1 : val2;
}
function round( val )
{
  return Math.floor( val + 0.5 );
}

// ------------------------------------------------------------------
// obtains the element's object by it's identifier
function obtainElementById( id )
{
  if ( document.getElementById )
    return document.getElementById( id );
  else
    return document.all( id );
}

// ------------------------------------------------------------------
// obtains the element's object by it's identifier
// in the document, given
function obtainElementByIdInDocument( id, documentObject )
{
  if ( documentObject.getElementById )
    return documentObject.getElementById( id );
  else
    return documentObject.all( id );
}

// ------------------------------------------------------------------
// returns the document, containing in the frame, given
function getFrameDocument( frame )
{
  if (frame.contentDocument) // For NS6
    return frame.contentDocument; 
  else if (frame.contentWindow) // For IE5.5 and IE6
    return frame.contentWindow.document;
  else if (frame.document) // For IE5
    return frame.document;
  else // damn!
    alert("Error: could not find frame's document");
}

// ------------------------------------------------------------------
// obtains the current window's cilient area width
function getWindowWidth()
{
  var scrollBarWidth = 20;
  if ( navigator.userAgent.indexOf("IE") >= 0 )
    scrollBarWidth = 0;
  return ( (document.all)? document.body.clientWidth : window.innerWidth ) - scrollBarWidth;
}

// ------------------------------------------------------------------
// obtains the current window's cilient area height
function getWindowHeight()
{
  return (document.all)? document.body.clientHeight : window.innerHeight;
}

// ------------------------------------------------------------------
// obtains the current document's width
function getDocumentWidth()
{
  // IE's value of client width includes the right scroll
  //  bar, but doesn't show at this area anything, so gotta
  // exclude it
  var scrollBarWidth = 0;
  if ( navigator.userAgent.indexOf("IE") >= 0 )
    scrollBarWidth = 20;
  return max( document.body.scrollWidth, document.documentElement.scrollWidth ) - scrollBarWidth;
}

// ------------------------------------------------------------------
// obtains the current document's height
function getDocumentHeight()
{
  return max( document.body.scrollHeight, document.documentElement.scrollHeight );
}

// ------------------------------------------------------------------
// obtains the current document's vertical scroll position
// (an offset of the top left corner of window from 0 to the top of the document)
function getDocumentVerticalScroll()
{
  return max( document.body.scrollTop, document.documentElement.scrollTop );
}

// ------------------------------------------------------------------
// obtains the current document's horizontal scroll position
// (an offset of the top left corner of the window from 0 to left outline of the document)
function getDocumentHorizontalScroll()
{
  return max( document.body.scrollLeft, document.documentElement.scrollLeft );
}

// ------------------------------------------------------------------
// returns the number of pixels, set for the value ('px' will be removed, if present)
// returns 0 on error
function getCssPixelsValue( elementStyleValue )
{
  if ( typeof( elementStyleValue ) == 'number' )
    return elementStyleValue;
  else if ( typeof( elementStyleValue ) == 'string' )
  {
    if ( elementStyleValue.match( /^\d\s*px$/im ) )
    {
      return 0 + elementStyleValue;
    }
  }
  else return 0;
}

// ------------------------------------------------------------------
// sets the element's width by its id, the size in pixels and
// other CSS dimensions are allowed
// the borders width will be excluded from the width, that will be set
// so to the value of the desired width will be with borders
function setElementWidthById( elementId, width )
{
  var element = obtainElementById( elementId );
  if ( element )
  {
    // to work on both: IE and good browsers
    if ( typeof( width ) == 'number' )
      element.style.width = width+"px";
    else
      element.style.width = width;
  }  
}

// ------------------------------------------------------------------
// sets the element's height by its id, the size in pixels and
// other CSS dimensions are allowed
// the borders width will be excluded from the height, that will be set
// so to the value of the desired height will be with borders
function setElementHeightById( elementId, height )
{
  var element = obtainElementById( elementId );
  if ( element )
  {
    // to work on both: IE and good browsers
    if ( typeof( height ) == 'number' )
      element.style.height = height+"px";
    else
      element.style.height = height;
  };
}

// ------------------------------------------------------------------
// obtains the element's width by its id
function getElementWidthById( elementId )
{
  var element = obtainElementById( elementId );
  if ( element )
    return element.offsetWidth;
  else
    return 0;
}

// ------------------------------------------------------------------
// obtains the element's height by its id
function getElementHeightById( elementId )
{
  var element = obtainElementById( elementId );
  if ( element )
    return element.offsetHeight;
  else
    return 0;
}

// ------------------------------------------------------------------
// sets the element's top coordinate by its id, the size in pixels and
// other CSS dimensions are allowed
function setElementTopById( elementId, top )
{
  var element = obtainElementById( elementId );
  if ( element )
  {
    // to work on both: IE and good browsers
    if ( typeof( top ) == 'number' )
      element.style.top = top+"px";
    else
      element.style.top = top;
  }  
}

// ------------------------------------------------------------------
// Sets the element top value to the of the bottom position and the
// element height.
// Fixed means that position of the element is calculated from the window
// coordinates, not the document coordinates (i.e. the scroll value is added)
function setElementBottomFixedById( elementId, bottom )
{
  var element = obtainElementById( elementId );
  if ( element )
  {
    var documentScroll = getDocumentVerticalScroll();
    var elementHeight = getElementHeightById( elementId );
    // to work on both: IE and good browsers
    if ( typeof( bottom ) == 'number' )
      element.style.top = bottom - elementHeight + documentScroll + "px";
    else
      element.style.top = bottom;
  }  
}

// ------------------------------------------------------------------
// sets the element's left coordinate by its id, the size in pixels and
// other CSS dimensions are allowed
function setElementLeftById( elementId, left )
{
  var element = obtainElementById( elementId );
  if ( element )
  {
    // to work on both: IE and good browsers
    if ( typeof( left ) == 'number' )
      element.style.left = left+"px";
    else
      element.style.left = left;
  };
}

// ------------------------------------------------------------------
// sets the required display state to the object, given
function setDisplayState( element, state )
{
  if ( !element || 
       !( ( state == "none" ) || ( state == "block" ) || ( state == "inline" ) ) ) 
    return 0;
    
  if ( element.style )
    element.style.display = state;
  else if ( element.display )
    element.display = state;
    
  return 1;
}

// ------------------------------------------------------------------
// obtains the display state for the element with ID, given
function getDisplayStateById( elementId )
{
  var element = obtainElementById( elementId );
  if ( element && element.style.display )
    return element.style.display;
  else
    return 0;
}

// ------------------------------------------------------------------
// sets the required visibility state to the object, given
function setVisibilityState( element, state )
{
  if ( !element || 
       !( ( state == "hidden" ) || ( state == "visible" ) ) ) 
    return 0;
    
  if ( element.style )
    element.style.visibility = state;
  else if ( element.visibility )
    element.visibility = state;
    
  return 1;
}

// ------------------------------------------------------------------
// obtains the visibility state for the element with ID, given
function getVisibilityStateById( elementId )
{
  var element = obtainElementById( elementId );
  if ( element && element.style.visibility )
    return element.style.visibility;
  else
    return 0;
}

// ------------------------------------------------------------------
// hides the element with the id given
function hideElementById( id )
{
  element = obtainElementById( id );
  return setVisibilityState( element, "hidden" );
}

// ------------------------------------------------------------------
// moves the focus to the element with the id given
function focusElementById( id )
{
  element = obtainElementById( id );
  if ( element && element.visible != false && !element.disabled )
  {
    try
    {
      element.focus();
    }
    catch ( e ) 
    {
      return 0;
    };
    return 1;
  }
  else return 0;
}

// ------------------------------------------------------------------
// shows the element with the id given
function showElementByID( id ) 
{
  element = obtainElementById( id );
  return setVisibilityState( element, "visible" );
}

// ------------------------------------------------------------------
// calculates the given element's position in absolute coordinates 
// goes recursively to the "body" and sums the relative positions of elements
// topOrLeft could be "Left" or "Top"
// if the element has fixed or absolute positioning, the parent
// elements is not to be taken into account
// but for fixed elements the document scroll position is added
function calculatePosition( element, topOrLeft )
{
  position = 0;
  while ( element )
  {
    if ( topOrLeft == "Top" || topOrLeft == "Left" )
    {
      position += element[ "offset" + topOrLeft ];
      
      // if the element has fixed or absolute positioning, the parent
      // elements must not to be taken into account
      if ( element.style.position == "absolute" )
        break; 
      // but for fixed elements the document scroll position must be
      // added
      else if ( element.style.position == "fixed" )
      {
        if ( topOrLeft == "Top" )
          position += getDocumentVerticalScroll();
        else
          position += getDocumentHorizontalScroll();
        break;
      };
      
      // moving to the parent element
      element = element.offsetParent;
    };  
  };
  return position;
}

// ------------------------------------------------------------------
// adds the global events listener
function setGlobalOnLoadEventListener( listener )
{
  if (window.addEventListener)
    window.addEventListener("load", listener, false);
  else if (window.attachEvent)
    window.attachEvent("onload", listener);
  else if (document.getElementById)
    window.onload = listener;
}

// ------------------------------------------------------------------
// returns the character (key) code of the event, specified
// (if any)
function getKeyCode( event )
{
  return ( event.charCode ) ? event.charCode : event.keyCode;
}

// ------------------------------------------------------------------
var htmlEscapeChars = new Array();
htmlEscapeChars["&"] = "&amp;";
htmlEscapeChars["\""] = "&quot;";
htmlEscapeChars["<"] = "&lt;";
htmlEscapeChars[">"] = "&gt;";
htmlEscapeChars["'"] = "&#039;";

// replaces "&", """, "'", ">" and "<" with their
// HTML entities
// same as PHP's htmlspecialchars( string, ENT_QUOTES )
function escapeHtmlCharacters( string )
{
	var tmpStr = string;
	for ( key in htmlEscapeChars )
		tmpStr = tmpStr.replace( eval( "/" + key + "/gi" ), htmlEscapeChars[key] );
	return tmpStr;
}

// unescapes HTML code (backward conversion for
// escapeHtmlCharacters() )
function unEscapeHtmlCharacters( string )
{
	var tmpStr = string;
	for ( key in htmlEscapeChars )
    do
    {
      var prevStr = tmpStr;
      tmpStr = tmpStr.replace( eval( "/" + htmlEscapeChars[key] + "/gi" ), key );
    }
    while ( prevStr != tmpStr );

  return tmpStr;
}

// returns true if the URL, given is seemt to be of valid URL string format
function isValidUrl( url )
{
  if ( url.match &&
       url.match( /^([^:]+):\/\/([^:\?\/\#]+)(:\d+|)([^\?\#]*)(\?[^\#]*|)(\#.*|)$/g ) )
    return true;
  else
    return false;
}

// returns the MSIE version, if the current browser is MSIE
function getMsieVersion()
{
  var msieVersion = navigator.userAgent.match(/MSIE (\d)/);
  if ( msieVersion && msieVersion[1] )
    return msieVersion[1];
  else
    return false;
}

// returns true if there is no items in the object or an array
function isEmpty( object )
{
  if ( object )
  {
    if ( object.length > 0 )
      return false;
    else
    {
      for ( var i in object )
        return false;
    };
  };
  
  // nothing prooves, that the object is not empty
  return true;
}