
var g_scroll_decor_collection = new Array();
//minimum height of menu
var SCROLL_DECOR_MIN_HEIGHT = 100;
var SCROLL_DECOR_TYPE_RELATIVE_PAGE_BODY = 1;
var SCROLL_DECOR_TYPE_ABSOLUTE_HEIGHT = 2;
//scroll timer
var g_a_scroll_decor_timer = new Array();

/************************************************
Desc	: The class holds the height of the main div. if it was changed - check
		  the scroller again
		  when we need scroller we restore their heights)
Params	: none
Return	: nothing
************************************************/
function ScrollDecorState()
{
	var o_proto = ScrollDecorState.prototype;

	//height of scrolling area div
	o_proto.AreaScrollHeight;
	//height of page body
	o_proto.BodyHeight;
	// store to state general parameters.
	o_proto.NeedStoreState;
	// store to state general parameters.
	o_proto.StoreState = ScrollDecorStoreState;
}

/************************************************
Desc	: store height of area and client height of scroll
Params	: none
Return	: nothing
************************************************/
function ScrollDecorStoreState(o_cont_wrapper)
{
    if(this.NeedStoreState == true)
    {
		this.AreaScrollHeight = o_cont_wrapper.Area.scrollHeight;
		this.BodyHeight = document.body.clientHeight;
		this.NeedStoreState = false;
	}
}

/************************************************
Desc	: The main class of scroll container.
Params	: none
Return	: nothing
************************************************/
function ScrollDecorWrapper()
{
    var o_proto = ScrollDecorWrapper.prototype;
    // main wrapper.
    o_proto.Wrapper;
    // up-scroller div.
    o_proto.Up;
    // down-scroller div.
    o_proto.Down;
    //height of up-scroller div
	o_proto.UpHeight;
	//height of down-scroller div
	o_proto.DownHeight;
    // scrolling area  div.
    o_proto.Area;
    // object source
    o_proto.Object;
    // function create
    o_proto.CreateDynamic = CreateWrapper;
    // set width
    o_proto.SetWidth = ScrollDecorSetWidth;
    // the handle scroller
    o_proto.HandleScroller = ScrollDecorHandleScroller;
    // set height
    o_proto.HeightStrategy;
    // the class init object strategy for calc height.
    o_proto.InitHeightStrategy = ContSrclInitHeightStrategy;

    o_proto.LaunchChange = ScrollDecorLaunchChange;
    // the state object
    o_proto.State;
}

/************************************************
Desc	: The function create wrapper, up, down and area div.
Params	: none
Return	: nothing
************************************************/
function CreateWrapper()
{
    var o_wrapper, o_area, o_up, o_down, o_src, s_src_id;
    o_src = this.Object;
    if(!o_src)
        return;
    s_src_id = o_src.uniqueID;

	//-----------------------------------------------------------------------
	//creating the scrolled div (main div)
	o_wrapper = document.createElement("div");
	o_wrapper.id = "ScrollDecorMainDiv_" + s_src_id;
	o_wrapper.style.overflowY = "hidden";
	this.Wrapper = o_wrapper;


	// insert wrapper to document
    this.Object = o_src.replaceNode(o_wrapper);

	//-----------------------------------------------------------------------
	//creating the up scroller
	o_up = document.createElement("div");
	o_up.id = "ScrollDecorUp_" + s_src_id;
	o_up.className = "ScrollDecorScroller";
	o_up.attachEvent("onmouseenter",ScrollDecorStartScrollDown);
	o_up.attachEvent("onmouseleave", ScrollDecorStopScroll);
	o_up_img = document.createElement("img");
	//o_up_img.src = "images/scroll_decor_up_disabled.gif";
	o_up_img.className = "ScrollDecorBtns";
	o_up.appendChild(o_up_img);
    this.Up = o_up;

	//-----------------------------------------------------------------------
	//creating the scrolling area
	o_area = document.createElement("div");
	o_area.id = "ScrollDecorArea" + s_src_id;
	o_area.className = "ScrollDecorScrollArea";
	o_area.appendChild(o_src);
	this.Area = o_area;


//-----------------------------------------------------------------------
	//creating the down scroller
	o_down = document.createElement("div");
	o_down.id = "ScrollDecorDown" + s_src_id;;
	o_down.className = "ScrollDecorScroller";
	o_down.attachEvent("onmouseenter", ScrollDecorStartScrollUp);
	o_down.attachEvent("onmouseleave", ScrollDecorStopScroll);
	o_down_img = document.createElement("img");
	//o_down_img.src = "images/scroll_decor_down_enabled.gif";
	o_down_img.className = "ScrollDecorBtns";
	o_down.appendChild(o_down_img);
    this.Down = o_down;


	//appending all parts of scrolled div together

	o_wrapper.appendChild(o_up);
	o_wrapper.appendChild(o_area);
	o_wrapper.appendChild(o_down);
	
	//o_up_img.width = "7px";
	//o_up_img.height = "9px";
	o_up_img.src = "images/scroll_decor_up_disabled.gif";
	
	//o_down_img.width = "7px";
	//o_down_img.height = "9px";
	o_down_img.src = "images/scroll_decor_down_enabled.gif"
	//alert(SetWidth);
	this.SetWidth();

	this.UpHeight = o_up.offsetHeight;
	this.DownHeight = o_down.offsetHeight;

	this.State = new ScrollDecorState();
	this.State.StoreState(this);

	this.InitHeightStrategy();

	this.HandleScroller();
}


/************************************************
Desc	: Set width for wrapper object.
Params	: none
Return	: nothing
************************************************/
function ScrollDecorSetWidth()
{

	var o_src = this.Object;
	var o_wrapper = this.Wrapper;

	if(o_src.width && o_src.width != "")
	{
		o_wrapper.style.width = o_src.width;
		o_src.style.width = "100%";
	}
	else if(o_src.style && o_src.style.width != "")
	{
		o_wrapper.style.width = o_src.style.pixelWidth;
		o_src.style.width = "100%";
	}
	/*
	else
	{
	    o_wrapper.style.width = o_src.offsetWidth;
	}
	*/
}


/************************************************
Desc	: the main function of scrolled div. the function handles the resizing
of
		  the div and check if it needs a scroller or not
Params	: none
Return	: nothing
************************************************/
function ScrollDecorHandleScroller()
{

	//the scrolled div has 3 inner divs: scroller up, scrolling area and scroller down
	var o_up = this.Up;
	var o_area = this.Area;
	var o_down = this.Down;

	//sets the height of the div
	this.HeightStrategy.SetHeight();
	//check if the div needs a scroller
	if(ScrollDecorNeedScroll(o_area))
	{
		//scroll is required
		o_up.style.display = "block";
		o_down.style.display = "block";
        // correct height
		o_area.style.height = o_area.offsetHeight-(this.UpHeight +
this.DownHeight);
	}
	else
	{
		//scroll is NOT required
		o_up.style.display = "none";
		o_down.style.display = "none";
	}
}

/************************************************
Desc	: resize o_div height and scrolling area height
Params	: none
Return	: nothing
************************************************/
function ContSrclInitHeightStrategy()
{
    var n_type_height_strategy =
parseInt(this.Object.getAttribute("scroll_decor_type", 10));
    if(n_type_height_strategy == SCROLL_DECOR_TYPE_ABSOLUTE_HEIGHT)
    {
        this.HeightStrategy = new ScrollDecorCalcHeighAbsoluteHeightStrategy();
        this.HeightStrategy.Init(this);
    }
    else
    {
        this.HeightStrategy = new
ScrollDecorCalcHeighRelativePageBodyStrategy();
        this.HeightStrategy.Init(this);
    }

}


/************************************************
Desc	: add new source object for create scroll wrapper.
Params	: o_src - new source object
Return	: nothing
************************************************/
function ScrollDecorAdd(o_src)
{
    // create object wrapper
    o_scroll_decor = new ScrollDecorWrapper();
    // store source
    o_scroll_decor.Object = o_src;
    // add to global collection the wrapper
    g_scroll_decor_collection.push(o_scroll_decor);
}


/************************************************
Desc	: The general function for starting create all wrappers.
Params	: none
Return	: nothing
************************************************/
function ScrollDecorStart()
{
    var i;
    var o_cont;
    var n_length = g_scroll_decor_collection.length;
    if(n_length == 0)
        return;
    for(i = 0; i < n_length; i++)
    {
        //g_scroll_decor_collection(i).
        o_cont = g_scroll_decor_collection[i];
        o_cont.CreateDynamic();
    }

    //set loop check on changes in div height
	window.setInterval("ScrollDecorChange()", 50);

}

/************************************************
Desc	:
Params	: none
Return	: nothing
************************************************/
function ScrollDecorChange()
{
    var i;
    var n_length = g_scroll_decor_collection.length;
    var o_scroll_decorator;

    if(n_length == 0)
        return;
    for(i = 0; i < n_length; i++)
    {
        g_scroll_decor_collection[i].LaunchChange();
    }
    for(i = 0; i < n_length; i++)
    {
        // get the decorator
        o_scroll_decorator = g_scroll_decor_collection[i]
        // store
        o_scroll_decorator.State.StoreState(o_scroll_decorator);
    }
    
}

/************************************************
Desc	: the function launches the ScrollDecorHandler() function if a change
			in height (of page body or of element or of rest of the elements) has
occurred.
		  the function is called on interval of 0.5 sec
Params	: none
Return	: nothing
************************************************/
function ScrollDecorLaunchChange()
{
	var o_wrapper, o_area;

    o_wrapper = this.Wrapper;
    o_area = this.Area;
    if(!o_wrapper)
        return;

    //window.status = this.Object.id + " : store body = " + this.State.BodyHeight +
    //    " body = " + n_body_height;
	if(this.State.AreaScrollHeight != o_area.scrollHeight
		|| this.State.BodyHeight != document.body.clientHeight)
	{

		this.HandleScroller();
		this.State.NeedStoreState = true;		
	}
}

/************************************************
Desc	: check if scroll is needed
Params	: o_area - the element we check (scrolling area of main scrolled div)
Return	: boolean. true - element exists &amp; scroll is required, false -
otherwise
************************************************/
function ScrollDecorNeedScroll(o_area)
{
	if(o_area.scrollHeight > o_area.clientHeight)
	{
		//window.status = ScrollDecorMenuTime();
		return 1;
	}

	return 0;
}

/************************************************
Desc	: get current time for the scrolling
Params	: none
Return	: nothing
************************************************/
function ScrollDecorMenuTime()
{
	var time = new Date();
	return time.valueOf();
}

function ScrollDecorStartScrollDown()
{
	ScrollDecorStartScroll(-1);
}

function ScrollDecorStartScrollUp()
{
	ScrollDecorStartScroll(+1);
}


/************************************************
Desc	: start the scrolling operation
Params	: dy - the speed and direction of change in the scroller
Return	: nothing
************************************************/
function ScrollDecorStartScroll(dy)
{	
	var o_wpapper;
	var src = window.event.srcElement;
	if(src.tagName == "IMG")
	    src = src.parentElement;
	//up & down get changed when the scrolling operation starts
	src.className = "ScrollDecorStartScroll";
	o_wpapper = src.parentElement;
	o_wpapper.setAttribute("scrollTime0", ScrollDecorMenuTime());
	o_wpapper.setAttribute("scrollTop0",
	o_wpapper.childNodes.item(1).scrollTop);
	g_a_scroll_decor_timer[o_wpapper.id] =
    window.setInterval("ScrollDecorMenuScroll('" + o_wpapper.id + "', " + dy + ")", 35);
	//window.status = o_wpapper.id;
}


/************************************************
Desc	: stop the scrolling operation
Params	: none
Return	: nothing
************************************************/
function ScrollDecorStopScroll()
{
	var src = window.event.srcElement;
	if(src.tagName == "IMG")
	    src = src.parentElement;
	var s_wrapper_id = src.parentElement.id;
	//up &amp; down get changed when the scrolling operation ends
	src.className = "ScrollDecorStopScroll";
	ScrollDecorClearScrollInterval(s_wrapper_id);	
}


/************************************************
Desc	: scrolling operation
Params	: id - the id of div to scroll
		  dy - the speed and direction of change in the scroller
Return	: nothing
************************************************/
function ScrollDecorMenuScroll(id, dy)
{
	var o_img;
	var o_wrapper = document.getElementById(id);
	var o_area = o_wrapper.childNodes.item(1);
	var y = o_wrapper.getAttribute("scrollTop0") +
				Math.round((ScrollDecorMenuTime() - o_wrapper.getAttribute("scrollTime0")) *0.050) * dy

	o_area.scrollTop = y;
	if (y != o_area.scrollTop)
	{
		ScrollDecorClearScrollInterval(id);

		if (o_area.scrollTop == 0)
			o_wrapper.childNodes.item(0).childNodes.item(0).src = "images/scroll_decor_up_disabled.gif";
		else
			o_wrapper.childNodes.item(2).childNodes.item(0).src = "images/scroll_decor_down_disabled.gif";
	}
	else if (dy < 0)
	{		
		o_img = o_wrapper.childNodes.item(2).childNodes.item(0);
		if(o_img.src.lastIndexOf("scroll_decor_down_enabled") == -1)
			o_img.src = "images/scroll_decor_down_enabled.gif";
	}
	else
	{
		o_img = o_wrapper.childNodes.item(0).childNodes.item(0);
		if(o_img.src.lastIndexOf("scroll_decor_up_enabled") == -1)
			o_img.src = "images/scroll_decor_up_enabled.gif";
	}
}

/************************************************
Desc	: clear object interval
Params	: s_name - name interval
Return	: nothing
************************************************/
function ScrollDecorClearScrollInterval(s_name)
{
    var n_timer = g_a_scroll_decor_timer[s_name];

	//window.status = s_name;
	if (n_timer)
	{
		window.clearInterval(n_timer);
		g_a_scroll_decor_timer[s_name] = null;
	}
}

/************************************************
Desc	: Class for calc height - relative body page
Params	: none
Return	: nothing
************************************************/
function ScrollDecorCalcHeighRelativePageBodyStrategy()
{
    var o_proto = ScrollDecorCalcHeighRelativePageBodyStrategy.prototype;
    // object container wrapper
    o_proto.Container;
    // min height of the wrapper
    o_proto.MinHeight;
    // init of the object
    o_proto.Init = ScrollDecorCalcHeighRelativePageBodyStrategyInit;
    // set height
    o_proto.SetHeight = ScrollDecorSetHeighRelativePageBodyStrategy;
}

/************************************************
Desc	: Init main parameters for calc height - relative body page
Params	: o_cont_wrapper - object container wrapper
Return	: nothing
************************************************/
function ScrollDecorCalcHeighRelativePageBodyStrategyInit(o_cont_wrapper)
{
    this.Container = o_cont_wrapper;
    // set min height of the wrapper.
    this.MinHeight =
this.Container.Object.getAttribute("scroll_decor_min_height");
    if( !this.MinHeight )
		this.MinHeight = SCROLL_DECOR_MIN_HEIGHT;
}

/************************************************
Desc	: calc height - relative body page
Params	: none
Return	: nothing
************************************************/
function ScrollDecorSetHeighRelativePageBodyStrategy()
{
    this.Container.Area.style.height = Math.max(this.MinHeight,
document.body.clientHeight);
}


/************************************************
Desc	: Class for calc height - absolute height
Params	: none
Return	: nothing
************************************************/
function ScrollDecorCalcHeighAbsoluteHeightStrategy()
{
    var o_proto = ScrollDecorCalcHeighAbsoluteHeightStrategy.prototype;
    // object container wrapper
    o_proto.Container;
    // min height of the wrapper
    o_proto.MaxHeight;
    // init of the object
    o_proto.Init = ScrollDecorCalcHeighAbsoluteHeightStrategyInit;
    // set height
    o_proto.SetHeight = ScrollDecorSetHeighAbsoluteHeightStrategy;
}

/************************************************
Desc	: Init main parameters for calc height - absolute height
Params	: o_cont_wrapper - object container wrapper
Return	: nothing
************************************************/
function ScrollDecorCalcHeighAbsoluteHeightStrategyInit(o_cont_wrapper)
{
    this.Container = o_cont_wrapper;
    // set min height of the wrapper.
    this.MaxHeight = this.Container.Object.getAttribute("scroll_decor_max_height");
}

/************************************************
Desc	: calc height - absolute height
Params	: none
Return	: nothing
************************************************/
function ScrollDecorSetHeighAbsoluteHeightStrategy()
{
    if(this.MaxHeight)
        this.Container.Area.style.height = Math.min(this.Container.Area.scrollHeight, this.MaxHeight);
        //this.Container.Area.style.height = this.MaxHeight;
}
