//  OBJECT FOR CHANGING TEXT IN TEXT INPUTS

function txt_input(id,text_string,class_name) // id of text input, necessary default value, class name on not writing
{
	this.obj = $(id);
	this.obj.parent = this;
	this.class_name = (class_name!='')?class_name:false; // if class name is not given we don't change it

	if(this.class_name)
	{
		Element.addClassName(this.obj,this.class_name)
	}
	
	this.value = text_string;
	this.obj.value = this.value;
	
	this.obj.onfocus = this.clear_value;
	this.obj.onblur = this.set_value;
}

txt_input.prototype.set_value = function()
{
	if(this.value=="")
	{
		this.value = this.parent.value;
		if(this.parent.class_name)
		{
			Element.addClassName(this,this.parent.class_name)
		}
	}
}
txt_input.prototype.clear_value = function()
{
	if(this.value==this.parent.value)
	{
		this.value = "";
		if(this.parent.class_name)
		{
			Element.removeClassName(this,this.parent.class_name)
		}
	}
}


//  FUNCTION FOR CHANGING CLASS ON HOVER

function hover_colors(default_class_name,new_class_name)
{
	arr = document.getElementsByClassName(default_class_name);
	
	i = 0;
	while(arr[i])
	{
		arr[i].onmouseover = function()
		{
			this.className = new_class_name;
		}
		arr[i].onmouseout = function()
		{
			this.className = default_class_name;
		}
		
		i++;
	}
}


//  DOM SWITCHERS

gecko = (navigator.userAgent.indexOf('Gecko')!=-1)?true:false;
opera = (navigator.userAgent.indexOf('Opera')!=-1)?true:false;
ie = (navigator.userAgent.indexOf('MSIE')!=-1)?true:false;
ie_50 = (navigator.userAgent.indexOf('MSIE 5.0')!=-1)?true:false;
ie_7 = (navigator.userAgent.indexOf('MSIE 7')!=-1)?true:false;


function get_id_num(a,b) { // getting item's number from its ID; a = ID, b = ID's base (i. e., without number)
	k_a = a.length;
	k_b = b.length;
	m = a.substr((k_b),(k_a-1));
	return m;
}

function move_to(a)
{
	document.location.href = a;
}


//  SHOWING BLOCKS ON SELECT CHANGE

function set_select(obj,block_name) // all blocks / lists / paragraphs must have the same name base plus number
{
	i = 0;
	while($(block_name + i))
	{
		$(block_name + i).style.display = 'none';
		i++;
	}
	
	if($(block_name + obj.value))
	{
		$(block_name + obj.value).style.display = 'block';
	}
}


// OBJECT FOR ROLLING / UNROLLING HIDDEN BLOCKS ON BUTTON CLICK

function set_roll_obj(butt,block,step_x,period) // parameters: button; block to roll/unroll; step at x in px; time period in seconds
// direction on x and direction on y are set by CSS ('top right' etc.)
{
	// setting class values 
	this.button = $(butt); // button
	this.button.parent = this;
	
	this.block = $(block); // outer hiding block
	this.block.parent = this;
	
	i = 0;
	while(this.block.childNodes[i])
	{
		if(this.block.childNodes[i].nodeName=='DIV')
		{
			this.block.child = this.block.childNodes[i]; // inner hidden block with content - should be set!
			break;
		}
		i++;
	}
	
	if(!this.block.child)
	{
		alert('Block with content should be set');
		return false;
	}
	else
	{
		this.max_x = this.block.child.offsetWidth;
		this.max_y = this.block.child.offsetHeight;
	}
	
	this.step_x = (!step_x)?5:step_x;
	this.step_y = (this.step_x*this.max_y)/this.max_x;
	this.period = (!period)?.01:period;
	
	this.width = this.height = 0; // temp variables for non-integer values (because browsers tend to floor them)
	
	this.roll = 'unroll'; // 'roll' - show, 'unroll' - hide; initial value must be negative to the desired direction
	
	
	// starting	dynamics
	
	this.block.roll_start = function()
	{
		this.style.visibility = 'visible';
		var roll = new PeriodicalExecuter(this.roll, this.parent.period, this);
	}
	this.block.roll = function(s)
	{
		this.caller.parent.width = ((this.caller.parent.width + this.caller.parent.step_x) >= this.caller.parent.max_x) ? this.caller.parent.max_x : (this.caller.parent.width + this.caller.parent.step_x);
		this.caller.parent.height = ((this.caller.parent.height + this.caller.parent.step_y)>=this.caller.parent.max_y) ? this.caller.parent.max_y: (this.caller.parent.height + this.caller.parent.step_y);
		
		this.caller.style.width = this.caller.parent.width + 'px';
		this.caller.style.height = this.caller.parent.height + 'px';
		
		if(this.caller.parent.roll == 'unroll')
		{
			s.stop();
		}
		
		if((this.caller.parent.width>=this.caller.parent.max_x)&&(this.caller.parent.height>=this.caller.parent.max_y))
		{
			s.stop();
		}
	}
	
	this.block.unroll_start = function()
	{
		var roll = new PeriodicalExecuter(this.unroll, this.parent.period, this);
	}
	this.block.unroll = function(s)
	{
		this.caller.parent.width = ((this.caller.parent.width - this.caller.parent.step_x) <= 0) ? 0 : (this.caller.parent.width - this.caller.parent.step_x);
		this.caller.parent.height = ((this.caller.parent.height - this.caller.parent.step_y) <= 0) ? 0: (this.caller.parent.height - this.caller.parent.step_y);
		
		this.caller.style.width = this.caller.parent.width + 'px';
		this.caller.style.height = this.caller.parent.height + 'px';
		
		if(this.caller.parent.roll == 'roll')
		{
			s.stop();
		}
		
		if((this.caller.parent.width<=0)&&(this.caller.parent.height<=0))
		{
			this.caller.parent.block.style.visibility = 'hidden';
			s.stop();
		}
	}
	
	
	this.button.onclick = function()
	{
		this.parent.roll= (this.parent.roll=='roll')?'unroll':'roll';
		if(this.parent.roll=='roll')
		{
			this.parent.block.roll_start();
		}
		else
		{
			this.parent.block.unroll_start();
		}
	}
}


// OBJECT FOR CHANGING LINKS TO SPANS ON NAVIGATING

function set_links(id,func,nobr,linked_obj) // parameters: id of parent element, function for onclick, if string must be in a NOBR, linked_object (temporary solution till Observers will be implemented)
/** 
properties:

this.list - container for elements
this.func - name of function handling clicks
this.nobr - true|false - should NOBR element be in the paragraph
this.format - 'list|par' - according to the type of the list
this.lis - [may be empty] - array of LI elements in container
this.current - number of the currently checked item; default = -1;
this.links - array of A elements and SPAN element
this.values - array of values of A elements and SPAN element (for IE)
this.ids - array of ids of A elements and SPAN element (for IE)

*all A elements have href attribute, SPAN element (if any) has id;
*/
{
	if($(id))
	{
		this.list = $(id);
		this.list.parent = this;
	}
	else
	{
		return false;
	}
	
	this.func = (func)?func:false;
	this.linked_obj = linked_obj;
	this.nobr = (nobr&&(nobr==true||(nobr==false)))?nav_type:true; // default nobr type is 'true'
	
	this.lis = this.list.getElementsByTagName('LI');
	
	if(this.lis.length>0)
	{
		this.format = 'list';
	}
	else
	{
		this.format = 'par';
	}
	
	this.current = -1; // presumably we have no current links in list
	
	get_nav_links(this.list);
	set_links_click(this);
	
}

function get_nav_links(obj) // getting all links and (possibly) span from the list
{
	obj.parent.links = new Array;
	obj.parent.values = new Array;
	obj.parent.ids = new Array;
	
	if(obj.parent.format=='list') // list case
	{
		i = j = 0;
		while(obj.childNodes[i])
		{
			if(obj.childNodes[i].nodeName=="LI")
			{
				if(obj.childNodes[i].firstChild.nodeName=="A")
				{
					obj.childNodes[i].firstChild.id = prereplace_it(obj.childNodes[i].firstChild.href);
				}
				
				if((obj.childNodes[i].firstChild.nodeName=="A")||(obj.childNodes[i].firstChild.nodeName=="SPAN"))
				{
					obj.parent.links[j] = obj.childNodes[i].firstChild;
					obj.parent.links[j].parent = obj.parent;
					obj.parent.ids[j] = obj.childNodes[i].firstChild.id;
					obj.parent.values[j] = obj.childNodes[i].firstChild.firstChild.nodeValue;
				}
				if(obj.childNodes[i].firstChild.nodeName=="SPAN")
				{
					obj.parent.current = j;
				}
				
				j++;
			}
			i++;
		}
	}
	else // paragraph case
	{
		i = j = 0;
		
		if(obj.parent.nobr)
		{
			set_nobr(obj);
			temp_obj = obj.firstChild;
		}
		else
		{
			temp_obj = obj;
		}
		
		while(temp_obj.childNodes[i])
		{
			if(temp_obj.childNodes[i].nodeName=="A")
			{
				temp_obj.childNodes[i].id = prereplace_it(temp_obj.childNodes[i].href);
			}
			if(temp_obj.childNodes[i].nodeName=="SPAN")
			{
				obj.parent.current = j;
			}
			if((temp_obj.childNodes[i].nodeName=="A")||(temp_obj.childNodes[i].nodeName=="SPAN"))
			{
				obj.parent.links[j] = temp_obj.childNodes[i];
				obj.parent.links[j].parent = obj.parent;
				obj.parent.ids[j] = temp_obj.childNodes[i].id;
				obj.parent.values[j] = temp_obj.childNodes[i].firstChild.nodeValue;
				j++;
			}
			i++;
		}
	}
}


function set_nobr(block_name)
{
	if($(block_name))
	{
		d = $(block_name);
		a = d.innerHTML;
		
		if(a.substr(0,6).toUpperCase()!='<NOBR>')
		{
			d.innerHTML = "<NOBR>" + a + "</NOBR>";
		}
	}
}

function prereplace_it(m) // parameters of id - '&' is changed to 'X', '=' - to '-' (requirements to id in w3 spec)
{
	re = /&/g;
	m = m.replace(re,'\X');
	re = /=/g;
	m = m.replace(re,'-');
	
	return m;
}

function replace_it(m) // parameters of id - '&' is changed to 'X', '=' - to '-' (requirements to id in w3 spec)
{
	re = /\X/g;
	m = m.replace(re,'&');
	re = /-/g;
	m = m.replace(re,'=');
	
	return m;
}

function set_links_click(obj) // setting handlers for links
{
	i = 0;
	while(obj.links[i])
	{
		if(obj.links[i].nodeName=='A')
		{
			obj.links[i].onclick = function()
			{
				for(i=0;i<this.parent.links.length;i++)
				{
					if(this.parent.format=='list')
					{
						if(this.parentNode == this.parent.links[i].parentNode) // quite a strange construction, truly; doesn't work without ".parentNode"
						{
							this.parent.current = i; // number of clicked item in the list
						}
					}
					else
					{
						if(this == this.parent.links[i])
						{
							this.parent.current = i; // number of clicked item in the list
						}
					}
				}
				
				links_reset_list(this.parent,this.parent.current);
				
				if(this.parent.func)
				{
					point = this.parent.links[this.parent.current]; // current item
					k = this.parent.current; // current position
					func = this.parent.func; // handler function
					linked_obj = this.parent.linked_obj; // linked object (BAD DECISION)
					
					param_arr = point.id.split('?');
					param = replace_it(param_arr[param_arr.length-1]);
					func_obj = this.parent;
					
					func(param,k,func_obj,linked_obj);
//					eval(func +  '("' + param + '",' + k + ',func_obj,linked_obj)'); // HERE OUR FUNCTION IS CARRIED OUT
				}
				
				get_nav_links(obj.list); // resetting list object
				set_links_click(obj);
				
				return false;
			}
		}
		i++;
	}
}

function links_reset_list(obj,k) // resetting items in this list
{
	if(obj.format=='par')
	{
		obj.list.innerHTML = '';
		if(obj.nobr)
		{
			var elem = document.createElement("NOBR");
			obj.list.appendChild(elem);
		}
	}
	
	j = obj.links.length;
	
	for(i=0;i<j;i++)
	{
		val = obj.values[i];
		if(i!=k) // normal A
		{
			var elem = document.createElement("A");
			elem.href = replace_it(obj.links[i].id);
		}
		else
		{
			var elem = document.createElement("SPAN");
		}
		elem.innerHTML = val;
		elem.id = obj.ids[i];
		
		if(obj.format=='par') // paragraph case
		{
			if(obj.nobr)
			{
				if(obj.list.childNodes[0].nodeName!='#text')
				{
					temp_node = obj.list.childNodes[0];
				}
				else
				{
					temp_node = obj.list.childNodes[1];
				}
			}
			else
			{
				temp_node = obj.list;
			}
			temp_node.appendChild(elem);
			
			
			if(i<(j-1))
			{
				var text_node = document.createTextNode(" ");
				temp_node.appendChild(text_node);
			}
		}
		else // list case
		{
			obj.lis[i].innerHTML = '';
			obj.lis[i].appendChild(elem);
		}
	}
}

// end of changing object


// OBJECT FOR CHANGING CHECKBOXES

function select_all(check_name) // items necessary: link, checkboxes, link for invertion; name base is the same
{
	if($(check_name + '_link'))
	{
		this.obj = $(check_name + '_link');
		this.obj.parent = this;
		
		this.childs = new Array;
		
		i = 0;
		while($(check_name + i))
		{
			this.childs[i] = $(check_name + i);
			i++;
		}
		
		this.flag = true;
		this.obj.onclick = function()
		{
			if(this.parent.flag)
			{
				i = 0;
				while(this.parent.childs[i])
				{
					this.parent.childs[i].checked = true;
					i++;
				}
				this.parent.flag = false;
			}
			else
			{
				i = 0;
				while(this.parent.childs[i])
				{
					this.parent.childs[i].checked = false;
					i++;
				}
				this.parent.flag = true;
			}
			return false;
		}
	}
	
	if($(check_name + '_invert_link'))
	{
		this.invert_obj = $(check_name + '_invert_link');
		this.invert_obj.style.cursor = 'pointer';
		this.invert_obj.parent = this;
		
		this.invert_obj.onclick = function()
		{
			i = 0;
			while(this.parent.childs[i])
			{
				if(this.parent.childs[i].checked == false)
				{
					this.parent.childs[i].checked = true;
				}
				else
				{
					this.parent.childs[i].checked = false;
				}
				i++;
			}
		}
	}
}


// OBJECT FOR CHANGING BLOCKS' DISPLAY

function change_display(link_block,hidden_block,display,class_name) // parameters: id of the block with onclick; id of the block shown/hidden; primary display setting (= css style); class name for link block at clicked condition
{
	this.lb, this.hb;
	if($(link_block))
	{
		this.lb = $(link_block); // block for click
	}
	if($(hidden_block))
	{
		this.hb = $(hidden_block); // block to show / hide
	}
	
	if(class_name != null)
	{
		this.class_name = class_name;
	}
	
	if((this.lb==undefined)||(this.hb==undefined))
	{
		return false;
	}
	
	this.lb.parent = this;
	this.hb.parent = this;
	this.hb.style.display = display;
	
	inherits(new Subject(), this.lb);
	
	this.lb.onclick = function()
	{
		a = ['action','']
		if(this.parent.hb.style.display == 'block')
		{
			Element.hide(this.parent.hb);
			Element.removeClassName(this.parent.lb,this.parent.class_name);
			a[1] = 'hide';
		}
		else
		{
			Element.show(this.parent.hb);
			Element.addClassName(this.parent.lb,this.parent.class_name);
			a[1] = 'show';
		}
		
		this.Notify(this,a);
		return false;
	}
}


// OBJECT FOR SHOWING FLOWING HINTS

function show_hint(hover,hint,x_dir,y_dir,class_name,overflow_block) // parameters: id of block for mouseover, id of hidden hint block, x direction for hidden block according to mouse (top|bottom), y direction (left|right), [class name for hover element on mouseover], [id of block with 'overflow' style (for Mozilla - one should put hints apart from parent blocks not to hide them)]
{
	this.hover_block, this.hint_block;
	this.show_hint_flag = false; // the hint block is hidden
	
	if($(hover))
	{
		this.hover_block = $(hover); // block for mouseover
	}
	if($(hint))
	{
		this.hint_block = $(hint); // hint block
	}
	
	if((this.hover_block==undefined)||(this.hint_block==undefined))
	{
		return false;
	}
	
	this.hover_block.parent = this;
	this.hint_block.parent = this;
	
	this.x_dir = (x_dir)?x_dir:'right';
	this.y_dir = (y_dir)?y_dir:'bottom';
	
	
	// getting default style propeties
	
	// hack for Firefox - because in the 'display: none' state 'left' and 'top' are set to '0px'
	if(Element.getStyle(this.hint_block,'visibility')=='visible')
	{
		Element.setStyle(this.hint_block,{visibility:'hidden'});
		Element.show(this.hint_block);
	}
	
	this.x = (this.x_dir=='right')?Number(get_digit(Element.getStyle(this.hint_block,'left'))):-Number(get_digit(Element.getStyle(this.hint_block,'right'))); // style properties left|right
	this.y = (this.y_dir=='top')?-Number(get_digit(Element.getStyle(this.hint_block,'bottom'))):Number(get_digit(Element.getStyle(this.hint_block,'top'))); // style properties top|bottom
	
	if(isNaN(this.x)) this.x = 0;
	if(isNaN(this.y)) this.y = 0;
	
	
	// hack for Firefox (end)
	if(Element.getStyle(this.hint_block,'visibility')=='hidden')
	{
		Element.setStyle(this.hint_block,{visibility:'visible'});
		Element.hide(this.hint_block);
	}
	
	
	this.overflow_block = ($(overflow_block))?$(overflow_block):false;
	this.class_name = (class_name)?class_name:false;
	
	// dynamics start
	
	this.hover_block.onmouseover = function(event)
	{
		Element.addClassName(this,this.parent.class_name);
		this.parent.show_hint_flag = true;
		Element.show(this.parent.hint_block);
	}
	
	this.hover_block.onmousemove = function(event)
	{
		x = Number(Event.x(event)) + this.parent.x;
		y = Number(Event.y(event)) + this.parent.y;
		
		event_elem = Event.element(event);
		
		if(ie&&event_elem!=this&&event_elem.nodeName=='IMG')
		{
			elem = Event.findElement(event, this.nodeName);
			tdxy = find_overflow(Event.element(event),elem); // delta because of the event target element
			
			x += tdxy[0];
			y += tdxy[1];
		}
		
		
		if(this.parent.overflow_block)
		{
			xy = find_overflow(this,this.parent.overflow_block);
			x += xy[0];
			y += xy[1];
		}
		
		if(isNaN(x)) x = 0;
		if(isNaN(y)) y = 0;
		
		if(this.parent.y_dir=='top')
		{
			Element.setStyle(this.parent.hint_block,{bottom:(-y + 'px')});
		}
		else
		{
			Element.setStyle(this.parent.hint_block,{top:(y + 'px')});
		}
		
		if(this.parent.x_dir=='right')
		{
			Element.setStyle(this.parent.hint_block,{left:(x + 'px')});
		}
		else
		{
			Element.setStyle(this.parent.hint_block,{right:(-x + 'px')});
		}
	}
	
	this.hover_block.onmouseout = function()
	{
		Element.removeClassName(this,this.parent.class_name);
		this.parent.show_hint_flag = false;
		start_hide_hint(this.parent.hint_block)
	}
	
	
	if(this.hover_block.firstChild) // cleaning A tag from the hover element - bugs in IE (bad decision, surely)
	{
		if(this.hover_block.firstChild.nodeName == 'A')
		{
			temp_value = this.hover_block.firstChild.innerHTML;
			temp_href = this.hover_block.firstChild.href;
			this.hover_block.innerHTML = temp_value;
			this.hover_block.href = temp_href;
			this.hover_block.onclick = function()
			{
				move_to(this.href);
			}
		}
	}
}

function get_digit(a) // getting digits from css properties with 'px'
{
	m = parseInt(a);
	return m;
}

function find_overflow(event_obj,obj) // finding offsets to the overflow object
{
	xy = new Array;
	c = event_obj;
	xy[0] = c.offsetLeft;
	xy[1] = c.offsetTop;
	
    while (c.offsetParent != null)
	{
		if(c.offsetParent != obj)
		{
		    c = c.offsetParent;
    		xy[0] += c.offsetLeft;
	    	xy[1] += c.offsetTop;
		}
    	else if (c.tagName == 'BODY')
		{
			xy[0] = 0;
			xy[1] = 0;
			break;
		}
		else
		{
			break;
		}
    }
	return xy;
}

function start_hide_hint(elem)
{
	a = new PeriodicalExecuter(end_hide_hint, .005,'',elem);
}
function end_hide_hint(s,elem)
{
	if(!elem.parent.show_hint_flag)
	{
		Element.hide(elem);
	}
	s.stop();
}

// end of flowing hints object



// OBJECT FOR SCROLLING EQUAL BLOCKS (TABLES, IMAGES ETC.)

function set_equal_obj_scroll(parent_block,blocks_name,axis,func,flow_type,nav_type,list,arr_l,arr_r,l_yes,l_no,r_yes,r_no,full_scroll) // parameters: hiding block where scrolling will take place; hidden blocks; direction of scrolling: 'h'|'v'; function for handling clicks; type of scrolling: 'step'|'flow'; navigation type: 'list'|'arrows' (arrows right/left or navigation list); [navigation list's id]; [arrows' id: left picture, right picture, src: left scrolling available, left scrolling not available, right scrolling available, right scrolling not available, full scroll (scrolling back to the first item when final item is reached)]

/**
properties:
this.parent_block - hiding block
this.blocks - Array - hidden blocks
this.axis - direction of scrolling
this.func - name of function handling clicks
this.current - currently visible item's number
this.flow_type - step|flow - type of scrolling; default is 'step'
this.nav_type - arrows|list - type of navigation block; default is 'arrows'

case 'list':
	this.list - navigation list itself

case 'arrows':
	this.arr_l - left arrow block
	this.arr_l_img - left arrow block image
	this.arr_l_img.scroll_avail - left arrow block image src when scrolling is available
	this.arr_l_img.scroll_not_avail - left arrow block image src when scrolling is not available
	
	this.arr_r - right arrow block
	this.arr_r_img - right arrow block image
	this.arr_r_img.scroll_avail - right arrow block image src when scrolling is available
	this.arr_r_img.scroll_not_avail - right arrow block image src when scrolling is not available
	
	(arrows may exist independently from one another)
	
	this.full_scroll - 'false'|'true' - scrolling back to the first item when final item is reached (or reversely) - default is 'false'


*/
{
	// parent block
	if($(parent_block))
	{
		this.parent_block = $(parent_block);
	}
	else
	{
		return false;
	}
	
	this.parent_block.parent = this;
	
	// hidden blocks
	this.blocks = new Array;
	
	i = 0;
	while($(blocks_name + i))
	{
		this.blocks[i] = $(blocks_name + i);
		this.blocks[i].parent = this;
		
		i++;
	}
	
	if(this.blocks.length==0||this.blocks.length==1)
	{
		return false;
	}
	hide_except(this.blocks,0);
	this.current = 0;
	
	
/*	this.parent_block.style.width = this.blocks[0].offsetWidth + 'px';
	this.parent_block.style.height = this.blocks[0].offsetHeight + 'px';*/
	
	
	this.axis = (axis)?axis:'h'; // default scroll direction is horisontal
	this.func = (func)?func:false; // function for additional actions
	
	this.flow_type = (flow_type&&(flow_type=='step'||(flow_type=='flow')))?flow_type:'step'; // default scrolling type is 'step'
	
	this.nav_type = (nav_type&&(nav_type=='list'||(nav_type=='arrows')))?nav_type:'arrows'; // default navigation type is 'arrows'
	
	if(this.nav_type=='list') // navigation type is 'list'
	{
		if($(list))
		{
			this.list = $(list);
		}
		else
		{
			return false;
		}
		
		this.nav_string = new set_links(this.list.id,set_equal_scroll,false,this);
	}
	else // navigation type is 'arrows'
	{
		this.arr_l, this.arr_r;
		if($(arr_l))
		{
			this.arr_l = $(arr_l);
			this.arr_l.img_parent = this;
			
			if(this.arr_l.firstChild.nodeName == 'A')
			{
				temp_value = this.arr_l.firstChild.innerHTML;
				temp_href = this.arr_l.firstChild.href;
				this.arr_l.innerHTML = temp_value;
			}
			
			if(this.arr_l.firstChild.nodeName == 'IMG')
			{
				this.arr_l_img = this.arr_l.firstChild;
				this.arr_l_img.scroll_avail = l_yes;
				this.arr_l_img.scroll_not_avail = l_no;
			}
		}
		if($(arr_r))
		{
			this.arr_r = $(arr_r);
			this.arr_r.img_parent = this;
			
			if(this.arr_r.firstChild.nodeName == 'A')
			{
				temp_value = this.arr_r.firstChild.innerHTML;
				temp_href = this.arr_r.firstChild.href;
				this.arr_r.innerHTML = temp_value;
			}
			
			if(this.arr_r.firstChild.nodeName == 'IMG')
			{
				this.arr_r_img = this.arr_r.firstChild;
				this.arr_r_img.scroll_avail = r_yes;
				this.arr_r_img.scroll_not_avail = r_no;
			}
		}
		
		if(this.arr_l!=undefined||this.arr_r!=undefined)
		{
			this.full_scroll = (full_scroll)?full_scroll:false;
			
			this.set_scroll_arrows();
			
			if(this.arr_l)
			{
				this.arr_l.onclick = function()
				{
					num = this.img_parent.current - 1;
					params = replace_it(this.img_parent.arr_r_img.id) + '&num=' + num;
					if(num>=0)
					{
						set_equal_scroll(params,num,'',this.img_parent);
					}
					else if(this.img_parent.full_scroll==true)
					{
						num = this.img_parent.blocks.length-1;
						set_equal_scroll(params,num,'',this.img_parent);
					}
					
					this.img_parent.set_scroll_arrows();
					return false;
				}
			}
			
			if(this.arr_r)
			{
				this.arr_r.onclick = function()
				{
					num = this.img_parent.current + 1;
					params = replace_it(this.img_parent.arr_r_img.id) + '&num=' + num;
					if(num<this.img_parent.blocks.length)
					{
						set_equal_scroll(params,num,'',this.img_parent);
					}
					else if(this.img_parent.full_scroll==true)
					{
						num = 0;
						set_equal_scroll(params,num,'',this.img_parent);
					}
					
					this.img_parent.set_scroll_arrows();
					return false;
				}
			}
		}
		
	}
}

function hide_except(blocks,num) // hiding all blocks except the necessary one
{
	i = 0;
	while(blocks[i])
	{
		if(i==num)
		{
			Element.show(blocks[i]);
		}
		else
		{
			Element.hide(blocks[i]);
		}
		i++;
	}
}

function set_equal_scroll(params,num,linked_obj,obj) // scrolling equal objects; 
// parameters of ajax request, current item number, [navigation list object], equal blocks object
{
	current = obj.current;
	
	if(obj.flow_type == 'step')
	{
		Element.show(obj.blocks[num]);
		hide_except(obj.blocks,num);
	}
	else if(obj.flow_type == 'flow')
	{
		
	}
	else
	{
		return false;
	}
	
	if(obj.func)
	{
		eval(obj.func + '(' + num + ',' + current + ',obj)'); // HERE OUR FUNCTION IS CARRIED OUT
	}
	
	obj.current = num;
}

set_equal_obj_scroll.prototype.set_scroll_arrows = function()
{
	if(this.full_scroll) // circle scrolling
	{
		if(this.arr_l)
		{
			this.arr_l_img.src = this.arr_l_img.scroll_avail;
		}
		if(this.arr_r)
		{
			this.arr_r_img.src = this.arr_r_img.scroll_avail;
		}
	}
	else // scrolling to any of ends
	{
		if(this.arr_l)
		{
			if(this.current>0)
			{
				this.arr_l_img.src = this.arr_l_img.scroll_avail;
			}
			else
			{
				this.arr_l_img.src = this.arr_l_img.scroll_not_avail;
			}
		}
		
		if(this.arr_r)
		{
			if(this.current<(this.blocks.length-1))
			{
				this.arr_r_img.src = this.arr_r_img.scroll_avail;
			}
			else
			{
				this.arr_r_img.src = this.arr_r_img.scroll_not_avail;
			}
		}
	}
}

// end of equal blocks object


// FUNCTION FOR CHECKING FORMS' TEXT INPUTS AND TEXTAREAS

function check_form()
{
	a = arguments;
	
	flag = true; // default presumption - all fields are filled
	execs = new Array;
	
	for(i=0;i<(a.length-1);i++)
	{
		if($F(a[i])=='')
		{
			flag = false;
			start_check_form($(a[i]),a[a.length-1],i);
		}
	}
	
	if(!flag)
	{
		return false;
	}
	else
	{
		return true;
	}
}

function start_check_form(elem,new_class,num)
{
	Element.addClassName(elem,new_class);
	args = new Array(elem,new_class);
	execs[num] = new PeriodicalExecuter(end_check_form, 1,'',args);
}
function end_check_form(s,args)
{
	Element.removeClassName(args[0],args[1]);
	s.stop();
}



// OBJECT FOR TAB NAVIGATION

function tab_nav(tab_nav_class,tab_content_class,active_class) // parameters: class name of navigation block; class name of corresponding content blocks; class name for active navigation block
/**
properties:
this.tab_navs - navigation blocks
this.tab_contents - content blocks
this.active_class - class name when navigation block is active
*/
{
	this.tab_navs = document.getElementsByClassName(tab_nav_class);
	this.tab_contents = document.getElementsByClassName(tab_content_class);
	
	this.active_class = active_class;
	
	if(this.tab_navs.length!=this.tab_contents.length) // it's strange if navigation tabs quantity doesn't fit content tabs quantity
	{
		return false;
	}
	
	n = this.tab_navs.length;
	for(i=0;i<n;i++)
	{
		a = this.tab_navs[i].getElementsByTagName('A'); // removing links from tabs
		if(a.length>0)
		{
			m = a.length;
			for(j=0;j<m;j++)
			{
				t = a[j].innerHTML;
				par = a[j].parentNode;
				if(a[j].nextSibling) // if there are other elements in it's parent
				{
					ns = a[j].nextSibling;
					if(ns.nodeName == '#text')
					{
						ns = ns.nextSibling;
					}
					
					par.removeChild(a[j]);
					new Insertion.Before(ns,t);
				}
				else // id A is the only element in its' parent
				{
					par.removeChild(a[j]);
					text = document.createTextNode(t);
					par.appendChild(text);
				}
			}
		}
		
		this.tab_navs[i].onclick = function(obj,num)
		{
			return function() // idea's taken from Lebedev's "Technogrette"
			{
				if(Element.hasClassName(this,obj.active_class)) // if element is already active
				{
					return false;
				}
				else
				{
					j = obj.tab_navs.length;
					for(i=0;i<j;i++)
					{
						if(i!=num) // other content blocks
						{
							Element.hide(obj.tab_contents[i]);
							if(Element.hasClassName(obj.tab_navs[i],obj.active_class))
							{
								Element.removeClassName(obj.tab_navs[i],obj.active_class)
							}
						}
						else // necessary content block
						{
							Element.show(obj.tab_contents[i]);
							Element.addClassName(obj.tab_navs[i],obj.active_class)
						}
					}
				}
			}
		}(this,i)
	}
}



// OBJECT FOR CHANGING PARAGRAPHS AND INPUTS

function par_input(par,input) // parameters: paragraph (object||id); text input (object||id)
/**
properties:
this.par - paragraph
this.input - text input

methods:
this.show_par() - show paragraph, hide input
this.show_input() - hide paragraph, show input
*/
{
	this.par = $(par);
	this.input = $(input);
	
	if(this.par==null || this.input==null)
	{
		return false;
	}
	
	if(this.par.innerHTML!=$F(this.input))
	{
		this.input.value = this.par.innerHTML;
	}
	
	this.show_par = function()
	{
			this.par.innerHTML = $F(this.input);
			if(this.par.innerHTML=='')
			{
				this.par.innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
			}
			Element.hide(this.input);
			Element.show(this.par);
	}
	this.show_input = function()
	{
			Element.hide(this.par);
			Element.show(this.input);
			this.input.focus();
	}
	
	this.par.onclick = function(obj)
	{
		return function()
		{
			obj.show_input();
		}
	}(this)
	
	this.input.onblur = function(obj)
	{
		return function()
		{
			obj.show_par();
		}
	}(this)
}



// MENU TOOLBAR

function menu_toolbar_item(block,img1,img2,func1,func2) // parameters: id of parent block; src of image in not pushed state; src of image in pushed state; handler function

/**
properties:
this.block - block with menu item
this.img - image in menu item

this.img_src1 - src for normal state
this.img_src2 - src for clicked state

this.state - 'true|false' - state of pushing on the button - default is 'false'
this.func1 - name of function caried out at pushing
this.func2 - name of function caried out when button is already pushed
*/
{
	// block itself
	if($(block))
	{
		this.block = $(block);
	}
	else
	{
		return false;
	}
	
	this.img = (this.block.getElementsByTagName('IMG').length>0)?this.block.getElementsByTagName('IMG')[0]:false;
	if(this.img)
	{
		this.img_src1 = img1;
		this.img_src2 = img2;
		
		this.img.src = this.img_src1;
	}
	
	this.state = false; // presumably button is not pushed
	this.func1 = func1;
	this.func2 = func2;
	

	this.block.onclick = function(obj)
	{
		return function(event)
		{
			if(obj.state) // item's in pushed state
			{
				if(obj.img)
				{
					obj.img.src = obj.img_src1;
				}
				func = obj.func2; // handler function
				
				eval(func +  '(obj)');
				obj.state = false;
			}
			else // item's in normal state
			{
				if(obj.img)
				{
					obj.img.src = obj.img_src2;
				}
				func = obj.func1; // handler function
				
				eval(func +  '(obj)');
				obj.state = true;
			}
		}
	}(this)
}



// 	OBJECT FOR SWITCHING LISTS DISPLAY

switch_list = function(main_list,class_name,display,full_link,show_src,hide_src) // parameters: top list; class name for LI element when clicked; primary display setting (= css style);  [link for full show/hide]; [src: when all lists are hidden; when all lists are shown]
/**
properties:
this.main_list - top list which contains all other lists (hidden at load)
this.lis - LI elements which have lists unside them
this.sublists - ULs inside main list (number in array corresponds to the this.lis array)
this.full_link - link for 
*/
{
	if(!$(main_list))
	{
		return false;
	}
	else
	{
		this.main_list = $(main_list);
	}
	
	lis_temp = main_list.getElementsByTagName('LI');
	this.lis = new Array;
	this.sublists = new Array;
	
	display = (display=='block')?'block':'none';
	this.flag = (display=='block')?true:false;
	
	// observer for every A element which has handler on it
	inherits(new Observer(), this);
	this.Update = function(main_obj)
	{
		return function(obj,a)
		{
			if(a[0]=='action')
			{
				if((a[1]=='hide')&&main_obj.flag)
				{
					main_obj.set_flag(false);
				}
				
				if(obj.parentNode.nodeName == 'LI')
				{
					if(a[1]=='show')
					{
						Element.addClassName(obj.parentNode,class_name);
					}
					else if(a[1]=='hide')
					{
						Element.removeClassName(obj.parentNode,class_name);
					}
				}
			}
		}
	}(this)
		
	
	var m = lis_temp.length;
	var j = 0;
	for(var i=0;i<m;i++)
	{
		sublists = lis_temp[i].getElementsByTagName('UL');
		if(sublists.length>0)
		{
			links = lis_temp[i].getElementsByTagName('A');
			this.lis[j] = new change_display(links[0],sublists[0],display,class_name);
			this.sublists[j] = sublists[0];
			
			this.lis[j].lb.AddObserver(this);
			
			j++;
		}
	}
	
	if($(full_link))
	{
		if($(full_link).getElementsByTagName('IMG').length>0)
		{
			this.full_link_img = $(full_link).getElementsByTagName('IMG')[0];
			this.show_src = show_src;
			this.hide_src = hide_src;
		}
		
		this.full_link = $(full_link);
		this.full_link.onclick = function(obj)
		{
			return function()
			{
				if(obj.sublists.length>0)
				{
					var m = obj.sublists.length;
					if(!obj.flag) // all are hidden
					{
						for(var j=0;j<m;j++)
						{
							Element.show(obj.sublists[j]);
						}
						obj.set_flag(true);
					}
					else // all are visible
					{
						for(var j=0;j<m;j++)
						{
							Element.hide(obj.sublists[j]);
						}
						obj.set_flag(false);
					}
				}
				
				return false;
			}
		}(this)
		
		this.set_flag = function(v) // v = true|false
		{
			this.flag = v;
			if(v)
			{
				this.full_link_img.src = this.hide_src;
			}
			else
			{
				this.full_link_img.src = this.show_src;
			}
		}
	}
}



// OBJECT FOR SETTING CHANGING BLOCKS

function change_blocks(par_block,class_name,list) // parameters: parent block; class name for hidden blocks (only inside parent block); paragraph/list of links
/**
properties:
this.par_block - parent block which contains all other blocks
this.blocks - hidden blocks which will change their 'display'
this.list - paragraph/list with links for changing
*/
{
	if(!$(par_block))
	{
		return false;
	}
	else
	{
		this.par_block = $(par_block);
	}
	
	if(!$(list))
	{
		return false;
	}
	else
	{
		this.list = $(list);
	}
	
	this.change_photos = function(main_obj)
	{
		return function(params,num,obj)
		{
			var n = main_obj.blocks.length;
			for(var i=0;i<n;i++)
			{
				if(i==num)
				{
					Element.show(main_obj.blocks[i]);
				}
				else
				{
					Element.hide(main_obj.blocks[i]);
				}
			}
		}
	}(this)
	
	this.blocks = document.getElementsByClassName(class_name,this.par_block);
	this.list_object = new set_links(this.list,this.change_photos,false);
}



