﻿var DirectionEnum = { Left:0, Right:1, Up:2, Down:3};

/************************************/
/*          DROPDOWN                */
/************************************/
var EZF_DropDown_Instance;
var EZF_DropDown = Class.create(
{
    initialize: function(dropdownClientId, topbarClientId, itemsContainerClientId, hiddenFieldClientId) 
    {     
        this.DropdownControlClientId = dropdownClientId;
        this.DropdownControl = $(this.DropdownControlClientId);
        
        this.ItemsContainerClientId = itemsContainerClientId;
        this.ItemsContainer = $(this.ItemsContainerClientId);
        
        this.HiddenFieldClientId = hiddenFieldClientId;
        this.HiddenField = $(this.HiddenFieldClientId);
        
        this.TopBarClientId = topbarClientId;
        this.TopBar = $(this.TopBarClientId);
                
        this.EffectStartOptions = {duration: .20, style:{ height: this.ItemsContainer.offsetHeight + "px"}};
        this.EffectPullUpOptions = {duration: .20, style:{ height: "0px"}};
        
        //Initial values
        this.ItemsContainer.style.height = "0px";

        //Handler
        this.OnDropdownControlMouseClick = this.DropdownControl_OnMouseClick.bindAsEventListener(this);
        this.OnDropdownControlMouseOver = this.DropdownControl_OnMouseOver.bindAsEventListener(this);
        this.OnDocumentMouseClick = this.Document_OnMouseClick.bindAsEventListener(this);
        
        this.OnListItemMouseOver = this.ListItem_OnMouseOver.bindAsEventListener(this);
        this.OnListItemMouseOut = this.ListItem_OnMouseOut.bindAsEventListener(this);
        this.OnListItemMouseClick = this.ListItem_OnMouseClick.bindAsEventListener(this);
        
        //Attach events
        Event.observe(this.TopBar, 'click', this.OnDropdownControlMouseClick); 
        Event.observe(this.TopBar, 'mouseover', this.OnDropdownControlMouseOver); 
        Event.observe(document, 'click', this.OnDocumentMouseClick); 
 
        var childItems = $(this.ItemsContainer).select("div");
        for(var i = 0; i < childItems.length; i ++)
        {
            var currentItem = childItems[i];
            Event.observe(currentItem, 'mouseover', this.OnListItemMouseOver); 
            Event.observe(currentItem, 'mouseout', this.OnListItemMouseOut); 
            Event.observe(currentItem, 'click', this.OnListItemMouseClick); 
        }
    },
    DropDown : function()
    {
        if(this.EffectStart != null)
        {
            this.EffectStart.start(this.EffectStartOptions);
        }
        else
        {
            this.EffectStart = new Effect.Morph(this.ItemsContainer, this.EffectStartOptions); 
        }
    },
    PullUp : function()
    {
        if(this.EffectStartPullUp != null)
        {
            this.EffectStartPullUp.start(this.EffectPullUpOptions);
        }
        else
        {
            this.EffectStartPullUp = new Effect.Morph(this.ItemsContainer, this.EffectPullUpOptions); 
        }
    },
    ToggleDropDown : function()
    {
        this.EffectToggle = new Effect.Morph(this.ItemsContainer, this.EffectStartOptions); 
    },
    DropdownControl_OnMouseClick : function(EventArgs)
    {
        this.DropDown();
    },
    DropdownControl_OnMouseOver : function(EventArgs)
    {
        this.DropdownControl.style.cursor = "pointer";
    },
    Document_OnMouseClick : function(EventArgs)
    {
        var element = EventArgs.element();
        if(element != this.ItemsContainer &&
            element.up() != this.ItemsContainer && 
            element != this.TopBar &&
            element.up() != this.TopBar) 
        {
            this.PullUp();    
        }
        
    },
    ListItem_OnMouseOver : function(EventArgs)
    {
        var element = EventArgs.element();
        if(!element.hasClassName('selected'))
        {
            element.addClassName('selected');
        }
    },
    ListItem_OnMouseOut : function(EventArgs)
    {
        var element = EventArgs.element();
        element.removeClassName('selected');
    },
    ListItem_OnMouseClick : function(EventArgs)
    {
        this.PullUp();
        var element = EventArgs.element();
        element.addClassName('selected');
        this.HiddenField.value = element.value;
        
    }
}); 


/************************************/
/*          MODAL POPUP             */
/************************************/
var EZF_Modal_Instance;
var EZF_Modal = Class.create(
{
    Id:'EZF_Modal',
    ClassName:'modal',
    initialize: function() 
    {     
        this.Id = "EZF_Modal";
        this.ClassName = "modal";
        this.Element = null;
        this.Utility = new EZF_Utility();
        this.Modal = null;
        this.EnsureElement();
        
        this.OnWindowResize = this.Window_OnResize.bindAsEventListener(this);
        Event.observe(window, 'resize', this.OnWindowResize); 
    },   
    Show: function()
    {   
        this.EnsureElement();
        this.RecalculaeDimensions();
        this.Element.style.visibility = 'visible';
    },
    Hide: function()
    {
        if(this.Element != null)
        {
            $(this.Element).remove();
            this.Element = null;
        }
    },
    RecalculaeDimensions : function()
    {
        if(this.Element != null)
        {
            var pageSize = this.Utility.GetPageSize();
            this.Element.style.width = pageSize[0]+"px";
            this.Element.style.height = pageSize[1]+"px";
        }
    },
    EnsureElement: function()
    {
        this.Element = $(this.Id);
        if(this.Element == null)//Only create if none exist
        {
            this.Element = document.createElement("div");
            this.Element.id = this.Id;
            this.Element.className = this.ClassName;
            
            var pageSize = this.Utility.GetPageSize();
               
            this.Element.style.width = pageSize[0]+"px";
            this.Element.style.height = pageSize[1]+"px";
            
            document.body.appendChild(this.Element);
        }
    },
    Window_OnResize : function(EventArgs)
    {
        this.RecalculaeDimensions();
    }
}); 

/************************************/
/*              POPUP               */
/************************************/
var EZF_Popup_Instance;

function ShowPopupText(text, header, useModal, closeOnClick)
{
    if(EZF_Popup_Instance == null)
    {
        EZF_Popup_Instance = new EZF_Popup();
    }
    
    EZF_Popup_Instance.ShowText(text, header, useModal, closeOnClick);
}

function ShowPopup(containerId, header, useModal, closeOnClick)
{
    if(EZF_Popup_Instance == null)
    {
        EZF_Popup_Instance = new EZF_Popup();
    }
    
    EZF_Popup_Instance.Show(containerId,header, useModal, closeOnClick);
}

function ShowPopup(containerId, header, useModal, closeOnClick, width, heigth)
{
    if(EZF_Popup_Instance == null)
    {
        EZF_Popup_Instance = new EZF_Popup();
    }
    
    EZF_Popup_Instance.Show(containerId,header, useModal, closeOnClick, width, heigth);
}
function HidePopup()
{
    if(EZF_Popup_Instance != null)
    {
        EZF_Popup_Instance.Hide();
    }
}

var EZF_Popup = Class.create(
{
    Id:'EZF_Popup',
    ClassName:'popupcontrol',
    initialize: function() 
    {     
        this.Id = "EZF_Popup";
        this.ClassName = "popupcontrol";
        this.Element = null;
        this.CloseBtn = null;
        this.Modal = new EZF_Modal();
        this.Utility = new EZF_Utility();

        this.EnsureElement();
        
        //Handler
        this.OnCloseBtnMouseClick = this.CloseBtn_OnMouseClick.bindAsEventListener(this);
        this.OnCloseBtnMouseOver = this.CloseBtn_OnMouseOver.bindAsEventListener(this);
        this.OnCloseBtnMouseOut = this.CloseBtn_OnMouseOut.bindAsEventListener(this);
        this.OnWindowScroll = this.Window_OnScroll.bindAsEventListener(this);
        this.OnWindowResize = this.Window_OnResize.bindAsEventListener(this);
        
        
        //Attach events
        Event.observe(this.Element, 'mouseover', this.OnCloseBtnMouseOver); 
        Event.observe(this.Element, 'mouseout', this.OnCloseBtnMouseOut); 
        Event.observe(window, 'scroll', this.OnWindowScroll); 
        Event.observe(window, 'resize', this.OnWindowResize); 
    },
    EnsureElement : function()
    {
        this.Element = $(this.Id);
        if(this.Element == null)//Only create if none exist
        {
            this.Element = document.createElement("div");
            this.Element.className = this.ClassName;
            this.Element.id = this.Id;

            this.Header = document.createElement("div");
            this.Header.className = "header";
            
            this.HeaderTextControl = document.createElement("span");
            this.Header.appendChild(this.HeaderTextControl);
            
            this.CloseBtnControl = document.createElement("div");
            this.CloseBtnControl.className = "closeBtn";
            this.Header.appendChild(this.CloseBtnControl);
            
            this.Header.appendChild(this.Utility.ClearDiv());
            
            this.Content = document.createElement("div");
            this.Content.className = "content";
            
            this.Element.appendChild(this.Header);
            this.Element.appendChild(this.Content);
            
            var form = null;
            for(var i=0; i < document.body.childNodes.length; i++)
            {
                if(document.body.childNodes[i].tagName == "FORM")
                {
                    form = document.body.childNodes[i];
                }
            }
            if(form != null)
            {
                form.appendChild(this.Element);
            }
        }

        this.HeaderTextControl.innerHTML = this.HeaderText;
    },
    Hide : function()
    {
        this.Modal.Hide();
        this.Element.style.display = "none";
        if(this.ContainerId != null)
        {
            $(this.ContainerId).style.display = "none";
            this.OriginalLocation.appendChild($(this.ContainerId));
        }
    },
    Show : function(containerId, headerText, useModal, closeOnClick, width, height)
    {    
        this.OriginalLocation = $(containerId).parentNode;
        this.ContainerId = containerId;
        this.HeaderText = headerText;
        this.CliseOnClick = closeOnClick;
        this.Content.innerHTML = "";
        this.EnsureElement();
        
        Event.stopObserving (this.Element, 'click', this.OnCloseBtnMouseClick);
        Event.stopObserving (this.CloseBtnControl, 'click', this.OnCloseBtnMouseClick);    
            
        if(this.CliseOnClick)
        {
            Event.observe(this.Element, 'click', this.OnCloseBtnMouseClick);
            Event.stopObserving(this.CloseBtnControl, 'click');
        }
        else
        {
            Event.observe(this.CloseBtnControl, 'click', this.OnCloseBtnMouseClick);
            Event.stopObserving(this.Element, 'click');
        }
        
        this.Content.appendChild($(containerId));

        $(containerId).style.display = "block";
        this.Element.style.display = "block";
        
        if(width != null)
        {
            this.Element.style.width = width + "px";
        }
        //this.Element.style.height = height + "px";
        
        var pageSize = this.Utility.GetPageSize();
        var scrollSize = this.Utility.GetScrollOffsets();
        var centeredPosition = this.Utility.GetCenterPosition();
        
        this.Element.style.left = centeredPosition[0] - (this.Element.offsetWidth/2) +"px";
        this.Element.style.top = centeredPosition[1] - (this.Element.offsetHeight/2) + "px";
        
        if(useModal != null || useModal == true)
        {
            this.Modal.Show();
        }
    },
    ShowText : function(errortext, headerText, useModal, closeOnClick)
    {
        this.HeaderText = headerText;
        this.CliseOnClick = closeOnClick;
        
        this.EnsureElement();
        
        this.Content.innerHTML = errortext;
        
        Event.stopObserving (this.Element, 'click', this.OnCloseBtnMouseClick);
        Event.stopObserving (this.CloseBtnControl, 'click', this.OnCloseBtnMouseClick);    
            
        if(this.CliseOnClick)
        {
            Event.observe(this.Element, 'click', this.OnCloseBtnMouseClick);
            Event.stopObserving(this.CloseBtnControl, 'click');
        }
        else
        {
            Event.observe(this.CloseBtnControl, 'click', this.OnCloseBtnMouseClick);
            Event.stopObserving(this.Element, 'click');
        }
        
        this.Element.style.display = "block";
        
        var pageSize = this.Utility.GetPageSize();
        var scrollSize = this.Utility.GetScrollOffsets();
        var centeredPosition = this.Utility.GetCenterPosition();
        
        this.Element.style.left = centeredPosition[0] - (this.Element.offsetWidth/2) +"px";
        this.Element.style.top = centeredPosition[1] - (this.Element.offsetHeight/2) + "px";
        
        if(useModal != null || useModal == true)
        {
            this.Modal.Show();
        }
    },
    CloseBtn_OnMouseClick : function(EventArgs)
    {
        this.Hide(this.ContainerId);
    },
    CloseBtn_OnMouseOver : function(EventArgs)
    {
        this.CloseBtnControl.style.cursor = "pointer";
    },
    CloseBtn_OnMouseOut : function(EventArgs)
    {
        this.CloseBtnControl.style.cursor = "normal";
    },
    Window_OnScroll : function(EventArgs)
    {
        var centeredPosition = this.Utility.GetCenterPosition();
        this.Element.style.left = centeredPosition[0] - (this.Element.offsetWidth/2) +"px";
        this.Element.style.top = centeredPosition[1] - (this.Element.offsetHeight/2) + "px";
    },
    Window_OnResize : function(EventArgs)
    {
        var centeredPosition = this.Utility.GetCenterPosition();
        this.Element.style.left = centeredPosition[0] - (this.Element.offsetWidth/2) +"px";
        this.Element.style.top = centeredPosition[1] - (this.Element.offsetHeight/2) + "px";
    }
});


/************************************/
/*              CART                */
/************************************/
var EZF_Cart_Instance;
var EZF_Cart = Class.create(
{
    Id:'EZF_Cart',
    ClassName:'cart',
    //initialize: function(ParentId, CartContents, deliveryCost, deliveryCostUpperlimit) 
    initialize: function(ParentId, CartContents, options) 
    {        
        this.Id = "EZF_Cart";
        this.Cart = CartContents;
        this.Element = null;
        this.Summary = null;
        this.Items = new Array();
        this.ParentElementId = ParentId;
        this.Utility = new EZF_Utility();
        this.options = options || {};

        this.options.localization = (options.localization || { btnGoToCart: 'Gå TIL KASSEN', txtProducts: 'vare(r)', txtTotal: 'Total' });             
                  
        this.EnsureElement(this.ParentElementId, this.Cart);
        
        //Event delegates
        this.OnElementMouseClickHandler = this.Element_OnMouseClick.bindAsEventListener(this);
        this.OnElementMouseOverHandler = this.Element_OnMouseOver.bindAsEventListener(this);
        this.OnElementMouseOutHandler = this.Element_OnMouseOut.bindAsEventListener(this);
        this.OnDocumentMouseClick = this.Document_OnMouseClick.bindAsEventListener(this);
        
        //Attach events
        Event.observe(this.Element, 'click', this.OnElementMouseClickHandler); 
        Event.observe(this.Element, 'mouseover', this.OnElementMouseOverHandler); 
        Event.observe(this.Element, 'mouseout', this.OnElementMouseOutHandler); 
        Event.observe(document, 'click', this.OnDocumentMouseClick); 
    },
    EnsureElement : function(parentId, cart)
    {
        this.Element = $(this.Id);
        if(this.Element == null)
        {
            this.Element = document.createElement("div");
            this.Element.id = this.Id;
            this.Element.className = this.ClassName;
                        
            //Summary
            this.Summary = document.createElement("div");
            this.Summary.id = "summary";
            
            this.SummaryStatusImage = document.createElement("div");
            this.SummaryStatusImage.id = "cart_status_icon";
            this.SummaryQuantity = document.createElement("span");
            this.SummaryTotalPrice = document.createElement("span");
            this.SummaryDropdownImage = document.createElement("div");
            this.SummaryDropdownImage.id = "cart_dropdown_icon";
            
            this.Summary.appendChild(this.SummaryStatusImage);
            this.Summary.appendChild(this.SummaryQuantity);
            this.Summary.appendChild(this.SummaryTotalPrice);
            this.Summary.appendChild(this.SummaryDropdownImage);

            this.Summary.appendChild(this.Utility.ClearDiv());
            
            this.BottomTotalPrice = document.createElement("div");
            this.BottomTotalPrice.className = "bottom_totalprice";
            
            this.TotalPriceValue = document.createElement("span");
            
            this.BottomTotalPrice.appendChild(this.TotalPriceValue);
            
            
            this.BottomCheckoutImage = document.createElement("div");
            this.BottomCheckoutImage.id = "bottom_checkout";
            // QAD - fix this when localization is implemented
            this.BottomCheckoutImage.innerHTML = "<a href=\"#\" class=\"mediumbutton\"><span class=\"buttonarrows\">>></span><span class=\"buttontext\">" + this.options.localization.btnGoToCart + "</span></a>";  
            Event.observe(this.BottomCheckoutImage, 'click', function(){$(this.BottomCheckoutImage).fire("EZF_Cart:Navigate")}.bindAsEventListener(this)); 
            //Event.observe(this.BottomCheckoutImage, 'mouseover', function(){ this.BottomCheckoutImage.style.cursor = "pointer"; }.bindAsEventListener(this)); 
                        
            this.Element.appendChild(this.Summary);
            
            this.CartItemContainer = document.createElement("div");
            this.Element.appendChild(this.CartItemContainer);
                        
            this.Render(cart);
                                                
            this.Element.appendChild(this.BottomTotalPrice);
            this.Element.appendChild(this.BottomCheckoutImage);
            
            this.Element.appendChild(this.Utility.ClearDiv());
            
            $(parentId).appendChild(this.Element);
        }        
    },
    Render : function(cart, toggle)
    {    
        //Clear old values
        this.Clear();
        this.SummaryQuantity.innerHTML = "";
        this.SummaryTotalPrice.innerHTML = "";
        this.SummaryStatusImage.className = "inactive";
        
        //Set children
        this.Items.clear();
 
        if(cart != null && cart.CartItems != null)
        {
            
        
            for(var i=0; i < cart.CartItems.length; i++)
            {
                var currentElement = cart.CartItems[i];               
                this.Items.push(new EZF_CartItem(this.CartItemContainer, currentElement));
            }
            
            if(cart.CartItems.length > 0 && cart.DeliveryCost != null){
                this.AddItem(cart.DeliveryCostHeader, cart.DeliveryCostText, cart.DeliveryCost, 1);
            }
            
            //Set summary
            if( cart.TotalQuantity > 0)
            {
                //If there are products in cart, show green image
                this.SummaryStatusImage.className = "active";
            }
            else
            {
                this.SummaryStatusImage.className = "inactive";
            }
            
            this.SummaryQuantity.innerHTML = cart.TotalQuantity + " " + this.options.localization.txtProducts;
            this.SummaryTotalPrice.innerHTML = cart.TotalPrice + ",-"; 
            
            this.TotalPriceValue.innerHTML = this.options.localization.txtTotal + ": " + cart.TotalPrice + ",-";    
        }else{
            this.SummaryQuantity.innerHTML = 0 + " " + this.options.localization.txtProducts;
            this.SummaryTotalPrice.innerHTML = 0 + ",-"; 
        }

        
        if(toggle != null && toggle == true)
        {
            this.ToggleCart();
        }
    },
    ShowCart : function(effectOptions)
    {
        this.EffectStartOptions = effectOptions;
        if(this.EffectStartOptions == null)
        {
            this.EffectStartOptions =   
                {
                    duration: .5, 
                    style:{ height: this.CalculateHeight() }
                };
        }
                
        if(this.EffectStart != null)
        {
            this.EffectStart.cancel();
            if(this.EffectEnd != null)
            {
                this.EffectEnd.cancel();
            }
        }
        this.EffectStart = new Effect.Morph(this.Element, this.EffectStartOptions); 
    },
    HideCart : function(effectOptions)
    {
        this.EffectEndOptions = effectOptions;
        if(this.EffectEndOptions == null)
        {
            this.EffectEndOptions = 
                {
                    delay : .5,
                    duration: .5, 
                    style:{ height: '14px' }                    
                }
        }
        if(this.EffectEnd != null)
        {
            this.EffectEnd.cancel();
            if(this.EffectStart != null)
            {
                this.EffectStart.cancel();
            }
        }
        this.EffectEnd = new Effect.Morph(this.Element, this.EffectEndOptions);        
    },
    ToggleCart : function()
    {
        this.EffectEndOptions = 
            {
                delay : 4,
                duration: .5, 
                style:{ height: '14px' }
            };
    
        this.EffectStartOptions =   
            {
                duration: .5, 
                style:{ height: this.CalculateHeight() },
                afterFinish: function() { this.HideCart(this.EffectEndOptions); }.bind(this)
            };
        
        this.ShowCart(this.EffectStartOptions);
    },
    Element_OnMouseClick : function(EventArgs)
    {
        //We are listeling to 2 click events. 1 on cart and 1 on whole page.
        //When u click on cart, first cart click is fired, then document click.
        //To prevent the 2nd click event we call Event.stop.
        Event.stop(EventArgs); 
        this.ShowCart();
    },
    Element_OnMouseOver : function(EventArgs)
    {
        this.ShowCart();
    },
    Element_OnMouseOut : function(EventArgs)
    {
        this.HideCart();
    },
    Document_OnMouseClick : function(EventArgs)
    {
        this.EffectEndOptions = 
            {
                fps: 30,
                delay : 0,
                duration: .3, 
                style:{ height: '14px' }
            };
            
        this.HideCart(this.EffectEndOptions);
    },
    CalculateHeight : function()
    {
        var result = 0;
        result += this.Summary.offsetHeight;
        if(this.Items.length > 0)
        {
            for(var i=0; i < this.Items.length; i++)
            {
                var current = this.Items[i];
                if(current.Element != null)
                {
                    result += current.Element.offsetHeight;
                }
            }
        }
        result += this.BottomTotalPrice.offsetHeight;
        result += this.BottomCheckoutImage.offsetHeight;
        return result + "px";  
    },
    AddItem : function(name, discription, price, quantity)
    {        
        var match;
        for(var i=0; i < this.Items.length; i++)
        {
            if(this.Items[i].Name == name)
            {
                //already in list then update
                match = this.Items[i];
            }
        }
        
        if(match == null)
        {
            var cartItem = new Object();
            cartItem.Name = name;
            cartItem.Discription = discription;
            cartItem.Quantity = 1;
            cartItem.TotalPrice = price;
            
            this.Items.push(new EZF_CartItem(this.CartItemContainer, cartItem));
        }
        else
        {   
            match.Price = price;
        }
    },
    Clear : function()
    {
        for(var i = 0; i < this.Items.length; i++)
        {
            this.Items[i].Remove();
        }
    }
}); 


/************************************/
/*          EZF_CartItem            */
/************************************/
var EZF_CartItem = Class.create(
{
    ClassName:'cartitem',
    initialize: function(parent, cartItem) 
    {   
        this.ParentElement = parent;
        this.Element = null;
        this.Name = cartItem.Name;
        this.Discription = cartItem.Discription;
        this.Price = cartItem.Price;   
        this.Quantity = cartItem.Quantity;
        this.TotalPrice = cartItem.TotalPrice;
        this.LinkToProduct = cartItem.ProductLink;
        this.Utility = new EZF_Utility();
        
        this.EnsureDOM(parent);
        
        //Event delegates
        this.OnMouseOverHandler = this.OnMouseOver.bindAsEventListener(this);
        this.OnMouseOutHandler = this.OnMouseOut.bindAsEventListener(this);
        this.OnMouseClikHandler = this.OnMouseClik.bindAsEventListener(this);
        
        //Attach events
        if(this.Name != "FRAGT")
        {
            Event.observe(this.Element, 'mouseout', this.OnMouseOutHandler); 
            Event.observe(this.Element, 'click', this.OnMouseClikHandler); 
            Event.observe(this.Element, 'mouseover', this.OnMouseOverHandler); 
        }
    },
    EnsureDOM : function(parent)
    {
        if(this.Element == null)
        {
            //Create HTML elements
            this.Element = document.createElement("div");
            this.Element.className = "cartitem";
            
            this.QuantityHTML = document.createElement("span");
            this.QuantityHTML.className = "quantity";
            this.NameHTML = document.createElement("div");
            this.NameHTML.className = "name";
            this.TotalPriceHTML = document.createElement("span");   
            this.TotalPriceHTML.className = "totalprice";
            this.DiscriptionHTML = document.createElement("div");
            this.DiscriptionHTML.className = "discription";
            
            //Append child elements
            this.Element.appendChild(this.QuantityHTML);
            this.Element.appendChild(this.NameHTML);     
            this.Element.appendChild(this.TotalPriceHTML);
            this.Element.appendChild(this.Utility.ClearDiv());
            this.Element.appendChild(this.DiscriptionHTML);
            this.Element.appendChild(this.Utility.ClearDiv());
            
            this.ParentElement.appendChild(this.Element);
        }
        
        //Update/Set values
        this.NameHTML.innerHTML = this.Name;
        this.DiscriptionHTML.innerHTML = this.Discription;
        this.QuantityHTML.innerHTML = this.Quantity  + " x ";
        this.TotalPriceHTML.innerHTML = this.TotalPrice + ",-";
    },
    Remove : function()
    {
        if(this.Element != null)
        {
            $(this.Element).remove();
        }
        
        this.OnMouseOverHandler = null;
        this.OnMouseOutHandler = null;
        
        this.Element = null;
        this.Name = null;
        this.Discription = null;
        this.Price = null;   
        this.Quantity = null;
        this.TotalPrice = null;
    },
    UpdateQuantity : function(quantity)
    {
        this.Quantity = quantity;
        this.EnsureDOM();
    },
    OnMouseOver : function(eventArgs)
    {
        this.Element.style.backgroundColor = "#bcbcbc";
        this.Element.style.cursor = "pointer";
        //Event.stop(eventArgs);
    },
    OnMouseOut : function(eventArgs)
    {
        this.Element.style.backgroundColor = "transparent";
        //Event.stop(eventArgs);
    },
    OnMouseClik : function(eventArgs)
    {
        window.location = this.LinkToProduct;
    }
}); 

/************************************/
/*          IMAGE SCROLLER          */
/************************************/

var EZF_ImageScroller
 = Class.create(
{
    Id:'EZF_ImageScroller',
    ClassName:'EZF_ImageScroller',
    initialize: function(containerId, imageData, maxNumberOfImagesInView) 
    {
        this.ContainerId = containerId;//ClientId of the container.
        this.Container = $(this.ContainerId);
        this.ImageData = imageData;
        this.NumberOfImages = maxNumberOfImagesInView;
        this.CurrentIndex = 0;
        this.ImageIndex = 0;
        this.CurrentActive;
        this.NotActive;
        this.Utility = new EZF_Utility();
        this.NumberOfImagesLoaded = 0;
        
        this.EnsureElement(this.Container);
    },
    EnsureElement : function(container)
    {
        this.Element = $(this.Id);
        if(this.Element == null)
        {
            this.Element = document.createElement("div");
            this.Element.className = "EZF_ImageScroller";
            container.appendChild(this.Element);
            
            this.RenderImagePlaceholder(this.Element);
        }
    },
    RenderImagePlaceholder : function(container)
    {
        //Render viewport
        this.ImageContainer = document.createElement("div");
        this.ImageContainer.className = "imagecontainer";
        
        //Render viewport
        this.Left = document.createElement("div");
        this.Left.className = "slider";
        this.CurrentActive = this.Left;
        
        this.RenderImages(this.Left);
        
        this.ImageContainer.appendChild(this.Left);
        container.appendChild(this.ImageContainer);
    },
    RenderImages : function(container)
    {
        //Render initial images
        for(var i=this.CurrentIndex; i < this.NumberOfImages ; i++)
        {
            if(this.ImageData[i] != null)
            {
                var element = this.CreateElement(this.ImageData[i]);
                if(i == this.NumberOfImages-1 )
                {
                    $(element).addClassName("last");
                }
                container.appendChild(element);
            }
            

        }
        container.appendChild(this.Utility.ClearDiv());
    },
    CreateElement : function(imageData)
    {
        var ScrollerItem = document.createElement("div");
        ScrollerItem.className = "scrollerItem";
        
        var image = document.createElement("img");
        
        image.src = imageData.first;
        image.alt = imageData.fourth;
        image.title = imageData.fourth;
        
        this.OnNewImageLoadHandler = this.OnImageLoad.bindAsEventListener(this, image);
        Event.observe(image, "load", this.OnNewImageLoadHandler.bind());
        
        var link = document.createElement("a");
        link.href = imageData.third;
        link.appendChild(image);
        ScrollerItem.appendChild(link);
        
        var price = document.createElement("div");
        
        
        price.className = "scrollerItemprice";
        
        var priceBest = document.createElement("div");
        priceBest.className = "normal";
        priceBest.innerHTML = imageData.second.BestPrice.Value + ",-";
        price.appendChild(priceBest);
        
        if(imageData.second.HasDicount)
        {
            var discount = 100 - Math.round((imageData.second.DiscountPrice.Value/imageData.second.NormalPrice.Value)*100);
            var priceDiscount = document.createElement("div");
            priceDiscount.className = "discount";
            priceDiscount.innerHTML = discount + "%";
            price.appendChild(priceDiscount);
        }
        
        price.appendChild(this.Utility.ClearDiv());
        ScrollerItem.appendChild(price);
        return ScrollerItem;
    },
    OnImageLoad : function(EventArgs)
    {
        this.NumberOfImagesLoaded++;
    },
    Forward : function()
    {
        this.Move(1);
    },
    Back : function()
    {
        this.Move(-1);
    },
    Move : function(indeks)
    {   
        if(!this.IsInAnimation)
        {   
        
            if(indeks > 0)
            {
                this.ImageIndex = this.ImageIndex + this.NumberOfImages; 
            }
            else
            {
                if((this.ImageIndex - this.NumberOfImages) < 0)
                {
                    this.ImageIndex = this.ImageData.length - (this.NumberOfImages - this.ImageIndex); 
                }
                else
                {
                
                    this.ImageIndex = this.ImageIndex - this.NumberOfImages; 
                }
            }
            
            var length = Math.ceil(this.ImageData.length / this.NumberOfImages);
            if(this.CurrentIndex + indeks >= 0)
            {
                this.CurrentIndex = (this.CurrentIndex + indeks) % length;

            }
            else
            {
                this.CurrentIndex = (length - this.CurrentIndex + indeks) % length

            }
            
            this.Right = document.createElement("div");
            this.Right.className = "slider";
            
            //Render initial images
            var count = 0;

            var startIndex = this.ImageIndex % this.ImageData.length;
            var endIndex = startIndex + this.NumberOfImages;
            
            for(var i=startIndex; i < endIndex; i++)
            {    
                var element = this.CreateElement(this.ImageData[i% this.ImageData.length]);
                    if(i == endIndex-1 )
                    {
                        $(element).addClassName("last");
                    }
                this.Right.appendChild(element);  
            }
            this.Right.appendChild(this.Utility.ClearDiv());
            
            this.Right.style.width = (this.NumberOfImages * 115) + "px";
            this.Right.style.left = this.ImageContainer.offsetWidth + "px";
            this.ImageContainer.appendChild(this.Right);
            
            this.NotActive = this.Right;
            
            var prefix = "";
            //We need to know whether we are going left or right in order to
            //set the left position of the new image. If we are moving forward, then the
            //left postion of the new will be +(width of image). If we are going backwards
            //the left position will be -(width of image).
            var left;
            var right;
            if(indeks > 0)
            {
                prefix = "-";
                this.Right.style.left = this.NotActive.offsetWidth + "px";
            }
            else
            {
                this.Right.style.left = -this.NotActive.offsetWidth + "px";
            }     
            
        //Move both images at the same time, when the animation is complete, remove the old image.
        //When the animation begins set a flag indicating animation is in progress. This way we can 
        //prevent the user from starting severel animation before the pevious ones have completed.
        this.IsInAnimation = true;
        
        new Effect.Parallel([
            new Effect.Morph(this.Left, { style: { left: prefix + this.Left.offsetWidth+"px" } }),
            new Effect.Morph(this.Right, { style: { left: '0px' } })], 
            {
                transition: Effect.Transitions.sinoidal,
                afterFinish: function() 
                {         
                    this.Left.remove();
                    this.Left = this.Right;
                    this.IsInAnimation = false;
                    this.NumberOfImagesLoaded = 0;

                }.bind(this)
            });  
        }  
    },
    SetIndex : function(indeks)
    {
        if(this.CurrentIndex + indeks >= 0)
        {
            this.CurrentIndex = (this.CurrentIndex + indeks) % this.ImageData.length;
        }
        else
        {
            this.CurrentIndex = (this.ImageList.length - this.CurrentIndex + indeks) % this.ImageData.length
        }
        return this.CurrentIndex;
    }
});

/************************************/
/*           IMAGE FADER            */
/************************************/
var EZF_ImageFader_Instance;
var EZF_ImageFader
 = Class.create(
{
    initialize: function(containerId, imageData) 
    { 
        this.ContainerId = containerId;//ClientId of the container.
        this.Container = $(this.ContainerId);
        this.ImageData = imageData;//Simple array of imageurls
        this.CurrentIndex = 0;

        
        //Initialize first image.
        this.CurrentImage = new Image();
        this.CurrentImage.src = this.ImageData[this.CurrentIndex].First;
        this.CurrentImage.alt = this.ImageData[this.CurrentIndex].Third;
        this.CurrentImage.title = this.ImageData[this.CurrentIndex].Third;
        
        this.CurrentImage.style.position = "absolute";
        this.CurrentImage.style.left = "0px";
        this.CurrentImage.style.top = "0px"
        this.CurrentImage.zIndex = "0";
        
        this.Link = document.createElement("a");
        this.Link.appendChild(this.CurrentImage);
        this.Link.href = this.ImageData[this.CurrentIndex].Second;
        
        this.Container.appendChild(this.Link);
        
        //Create periodical executer (runs forever untill its stopped manual by callec stop())
        //Calls ChangeImage every 5 seconds.
        this.PeriodicalExecuter = new PeriodicalExecuter(this.ChangeImage.bindAsEventListener(this), 5);
    },
    ChangeImage : function()
    {
        this.CurrentIndex = (this.CurrentIndex+1)%this.ImageData.length;   
        this.InitializeImage(this.ImageData[this.CurrentIndex]);
    },
    InitializeImage : function(imageData)
    {   
        var newImage = new Image();
        newImage.src = imageData.First;
        newImage.alt = imageData.Third;
        newImage.title = imageData.Third;
        newImage.style.opacity = "0";
        newImage.style.filter = "alpha(opacity=0)";
        newImage.style.position = "absolute";
        newImage.style.left = "0px";
        newImage.style.top = "0px"
        newImage.style.zIndex = "1";

        this.Link.appendChild(newImage);
        this.Link.href = this.ImageData[this.CurrentIndex].Second;
        
        new Effect.Morph(newImage, { style: { opacity: '1' },
            duration: 1,
            transition: Effect.Transitions.sinoidal,
            afterFinish: function() 
            {
                Element.remove(this.CurrentImage);
                this.CurrentImage = newImage;
                this.CurrentImage.style.zIndex = "0";
                
            }.bind(this)   
        }); 
    } 
});


/************************************/
/*           IMAGE ROTATER          */
/************************************/
var EZF_ImageRotater_Instance;
var EZF_ImageRotater
 = Class.create(
{
    initialize: function(containerId, imageList) 
    { 
        this.ContainerId = containerId;//ClientId of the container.
        this.Container = $(this.ContainerId);
        this.ImageList = imageList;//Simple array of imageurls
        this.CurrentIndex = 0;
        this.IsInAnimation = false;
        //Show the first image in list
        this.ActiveImage = document.createElement("img");
        this.ActiveImage.src = this.ImageList[0].First;
        this.ActiveImage.alt = this.ImageList[0].Third;
        this.ActiveImage.title = this.ImageList[0].Third;
        
        if(this.Container != null)
        {
            this.Container.appendChild(this.ActiveImage);
        }
        
        if(this.ImageList.length > 1)
        {
            this.CreateButtons();
            
            this.Wait = null;
            if(this.Wait == null)
            {
                this.Wait = document.createElement("div");
                this.Wait.className = "preloader";
                this.Container.appendChild(this.Wait);
                this.Wait.style.left = (this.Container.offsetWidth/2) - (this.Wait.offsetWidth/2) + "px";
                this.Wait.style.top = (this.Container.offsetHeight/2) - (this.Wait.offsetHeight/2) + "px";
                this.Wait.style.display = "none";            
            }
            
            //Event delegates
            this.OnActiveImageMouseOverHandler = this.OnActiveImageMouseOver.bindAsEventListener(this);
            this.OnActiveImageMouseOutHandler = this.OnActiveImageMouseOut.bindAsEventListener(this);
            
            //Attach events
            Event.observe(this.ActiveImage, 'mouseover', this.OnActiveImageMouseOverHandler);         
            Event.observe(this.ActiveImage, 'mouseout', this.OnActiveImageMouseOutHandler);   
        }  
        else
        {
            this.OnActiveImageMouseOverSingleHandler = this.OnActiveImage_MouseOver.bindAsEventListener(this);
            Event.observe(this.ActiveImage, 'mouseover', this.OnActiveImageMouseOverSingleHandler);     
        }
        
        this.OnActiveImageMouseClickHandler = this.OnActiveImage_MouseClick.bindAsEventListener(this);
        Event.observe(this.Container, 'click', this.OnActiveImageMouseClickHandler); 
    },
    CreateButtons : function()
    {
        this.Button = document.createElement("div");
        this.Button.id = "sliderbutton";
        this.Button.className = "sliderbutton";
        this.ButtonText = document.createTextNode(this.ImageList.length + " billeder") ;
    
        this.Button.appendChild(this.ButtonText);
            
        this.Container = $(this.ContainerId);
        if(this.Container != null)
        {
            this.Container.appendChild(this.Button);
            this.Button.style.left = (this.Container.offsetWidth/2) - (95/2) + "px";
            $(this.Button).hide();
        }
        
        //Event delegates
        this.OnButtonMouseOverHandler = this.OnButtonMouseOver.bindAsEventListener(this);
        this.OnButtonMouseOutHandler = this.OnButtonMouseOut.bindAsEventListener(this);
        this.OnButtonMouseClickHandler = this.OnButtonMouseClick.bindAsEventListener(this);
                        
        //Attach events
        Event.observe(this.Button, 'mousemove', this.OnButtonMouseOverHandler); 
        Event.observe(this.Button, 'mouseout', this.OnButtonMouseOutHandler); 
        
        Event.observe(this.Button, 'click', this.OnButtonMouseClickHandler); 
    },
     OnActiveImageMouseOver : function(EventArgs)
    {
        Event.stop(EventArgs); 
        this.Button.style.display = "block";
        this.ActiveImage.style.cursor = "pointer";
    },
    OnActiveImageMouseOut : function(EventArgs)
    {       
        Event.stop(EventArgs); 
        
        /* IGNORE SOME OF THE MOUSEOUTS BECOS THEY ARE MOUSEOUNT ON A CHILD */
        var tg = (window.event) ? EventArgs.srcElement :EventArgs.target;
        var relTarg = EventArgs.relatedTarget || EventArgs.toElement;
        if(relTarg == this.Button)
        {
            return false;
        }
        this.Button.style.display = "none";
    },
    OnButtonMouseOut : function(eventArgs)
    {
        Event.stop(eventArgs); 
        this.Button.className = "sliderbutton";
    },
    OnButtonMouseOver : function(EventArgs)
    {
        Event.stop(EventArgs); 
        
        this.Container = $(this.ContainerId);
        
        var x = EventArgs.layerX || EventArgs.offsetX;
        if (x >= 0 && x < 15) 
        {
            this.Button.style.cursor = "pointer";
            this.Button.className = "sliderbutton left";
        }
        if (x >= 15 && x < 80) 
        {
            this.Button.className = "sliderbutton";
        }
        if (x >= 80 && x <= 95) 
        {
            this.Button.style.cursor = "pointer";
            this.Button.className = "sliderbutton right";
        }  
    },
    OnButtonMouseClick : function(EventArgs)
    {   
        //alert("OnButtonMouseClick");
        Event.stop(EventArgs); 
        var x = EventArgs.layerX || EventArgs.offsetX;
        if (x >= 0 && x < 15) 
        {
            this.Move(-1);
        }
        if (x >= 80 && x <= 95) 
        { 
            this.Move(1);
        }  
    },
    OnActiveImage_MouseClick : function(EventArgs)
    {
        $(this.ActiveImage).fire("EZF_ImageRotater:ActiveImageClick", {ActiveImage:this.ActiveImage, NavigateTo: this.ImageList[this.CurrentIndex].Second});
    },
    OnActiveImage_MouseOver : function(EventArgs)
    {
        this.ActiveImage.style.cursor = "pointer";
    },
    Move : function(indeks)
    {
        if(!this.IsInAnimation)
        {   
            //this.ActiveImage   
            if(this.Container != null)//If container is null then its been removed from dom, and no need for any effect.
            {
                if(this.CurrentIndex + indeks >= 0)
                {
                    this.CurrentIndex = (this.CurrentIndex + indeks) % this.ImageList.length;
                }
                else
                {
                    this.CurrentIndex = (this.ImageList.length - this.CurrentIndex + indeks) % this.ImageList.length
                }
                
                var newImage = document.createElement("img");// document.createElement("img");
                //this.Wait.style.display = "block"; 
                
                               
                this.ButtonText.data = (this.CurrentIndex % this.ImageList.length) + 1 + "/" + this.ImageList.length; 
                
                var prefix = "";
                
                //We need to know whether we are going left or right in order to
                //set the left position of the new image. If we are moving forward, then the
                //left postion of the new will be +(width of image). If we are going backwards
                //the left position will be -(width of image).
                if(indeks > 0)
                {
                    newImage.style.left = this.Container.offsetWidth + "px";
                    prefix = "-";
                }
                else
                {
                    newImage.style.left = -this.Container.offsetWidth + "px";
                }
                
                this.OnNewImageLoadHandler = this.OnNewImageLoad.bindAsEventListener(this, newImage, prefix);
                Event.observe(newImage, "load", this.OnNewImageLoadHandler.bind());
                Event.observe(newImage, 'mouseover', this.OnActiveImageMouseOverHandler); 
                newImage.src = this.ImageList[this.CurrentIndex].First;
                newImage.alt = this.ImageList[this.CurrentIndex].Third;
                newImage.title = this.ImageList[this.CurrentIndex].Third;
            }
        }
    },
    OnNewImageLoad : function(EventArgs)
    {
        
        var newImage = $A(arguments)[1];
        var prefix = $A(arguments)[2];
        
        this.Container.appendChild(newImage);
        
        this.OnActiveImageMouseOverHandler = this.OnActiveImageMouseOver.bindAsEventListener(this);
        this.OnActiveImageMouseOutHandler = this.OnActiveImageMouseOut.bindAsEventListener(this);
        
        //Attach events
        Event.observe(newImage, 'mouseover', this.OnActiveImageMouseOverHandler);         
        Event.observe(newImage, 'mouseout', this.OnActiveImageMouseOutHandler);   
        
        //Move both images at the same time, when the animation is complete, remove the old image.
        //When the animation begins set a flag indicating animation is in progress. This way we can 
        //prevent the user from starting severel animation before the pevious ones have completed.
        this.IsInAnimation = true;
        
        new Effect.Parallel([
            new Effect.Morph(this.ActiveImage, { style: { left: prefix + this.Container.offsetWidth+"px" } },{duration: 0.5}),
            new Effect.Morph(newImage, { style: { left: '0px' } })], 
            {
                duration: 0.5,
                transition: Effect.Transitions.sinoidal,
                afterFinish: function() 
                {   
                    this.ActiveImage.remove();
                    this.ActiveImage = newImage;
                    this.IsInAnimation = false;
                    //this.Wait.style.display = "none";
                    
                    //Shop.activateVariationSlider(thumbContainer);
                }.bind(this)
            });  
    }
});

/************************************/
/*              UTILITY             */
/************************************/

var EZF_Utility = Class.create(
{
    initialize: function() 
    { 
    },
    ClearDiv : function()
    {   
        var clearDiv = document.createElement("div");
        clearDiv.className = "clear";
        return clearDiv;
    },
    LogConsole : function(message)
    {
        if(window.console && window.console.firebug)
        {
            console.log(message);
        }
    },
	IsNumberKey : function(charCode)
	{
	    if(charCode > 48 && 57 > charCode)
	    {
	        return true;
	    }
	    return false;
	},
	IsLetterKey : function(charCode)
	{
	    if((charCode >= 65 && 90 >= charCode) ||  (charCode >= 97 && 122 >= charCode) ||  
            charCode == 192 || charCode == 221 || charCode == 222)
	    {
	        return true;
	    }
	    return false;
	},
	IsAllowedSpecialKey : function(charCode)
	{
	    //8 = backspace
	    return (charCode == 8);
	},
	IsArrowKey: function(charCode)
	{
        return (charCode <= 40 && charCode >= 37);
	},
	IsEnterKey: function(charCode)
	{
        return charCode == 13;
	},
	GetArrowDirection : function(charCode)
	{
	    
	    if(this.IsArrowKey(charCode))
	    {
            switch (charCode)
            {
                case 37:
                    return DirectionEnum.Left;
                case 38:
                    return DirectionEnum.Up;
                case 39:
                    return DirectionEnum.Right;
                case 40:
                    return DirectionEnum.Down;
            }	    
	    }
        return null;
	},
    GetPageSize: function()//This method is taken form lightbox.js 
    {        
	    var xScroll, yScroll;
    	
	    if (window.innerHeight && window.scrollMaxY) {	
	        xScroll = document.body.scrollWidth + window.scrollMaxX;
		    //xScroll = window.innerWidth + window.scrollMaxX //document.body.scrollWidth;
		    yScroll = window.innerHeight + window.scrollMaxY;
	    } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		    xScroll = document.body.scrollWidth;
		    yScroll = document.body.scrollHeight;
	    } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
	        //ORIGINAL LIGHTBOX JS WAS WRONG
		    xScroll = document.documentElement.scrollWidth;
		    yScroll = document.documentElement.scrollHeight;
		    
	    }
    	
	    var windowWidth, windowHeight;
	    if (self.innerHeight) {	// all except Explorer
		    windowWidth = self.innerWidth;
		    windowHeight = self.innerHeight;
	    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		    windowWidth = document.documentElement.clientWidth;
		    windowHeight = document.documentElement.clientHeight;
	    } else if (document.body) { // other Explorers
		    windowWidth = document.body.clientWidth;
		    windowHeight = document.body.clientHeight;
	    }	
    	
	    // for small pages with total height less then height of the viewport
	    if(yScroll < windowHeight){
		    pageHeight = windowHeight;
	    } else { 
		    pageHeight = yScroll;
	    }

	    // for small pages with total width less then width of the viewport
	    if(xScroll < windowWidth)
	    {	
	        //if there is a scrollbar on left side, windowWidth is not good cos
	        //its too big, and a horisontal scrollbar will appear. Instead use
	        //xscroll which is the width without the scrollbar width
	        if(yScroll > windowHeight)
	        {
	            pageWidth = xScroll;
	        }
	        else
	        {
	            pageWidth = windowWidth;
	        }
		    
	    } else {
		    pageWidth = xScroll;
	    }


	    arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
	    return arrayPageSize;
    },
    GetWindowSize : function()
    {
		var windowWidth, windowHeight;
		
		if (self.innerHeight) 
		{	// all except Explorer
			if(document.documentElement.clientWidth)
			{
				windowWidth = document.documentElement.clientWidth; 
			} else 
			{
				windowWidth = self.innerWidth;
			}
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight)
        {   // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) 
		{ 
		    // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	
		
		return [windowWidth,windowHeight];
    },
alertSize : function() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  alert( 'Width = ' + myWidth );
  alert( 'Height = ' + myHeight );
},
    GetScrollOffsets : function()
    {
       var scrOfX = 0, scrOfY = 0;
      if( typeof( window.pageYOffset ) == 'number' ) {
        //Netscape compliant
        scrOfY = window.pageYOffset;
        scrOfX = window.pageXOffset;
      } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
        //DOM compliant
        scrOfY = document.body.scrollTop;
        scrOfX = document.body.scrollLeft;
      } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
        //IE6 standards compliant mode
        scrOfY = document.documentElement.scrollTop;
        scrOfX = document.documentElement.scrollLeft;
      }
      return [ scrOfX, scrOfY ];
    },
    GetCenterPosition : function()
    {
        var windowSize = this.GetWindowSize();
        var scroll = this.GetScrollOffsets();
        
        return [(windowSize[0]/2) + scroll[0], (windowSize[1]/2) + scroll[1]];
    }
});


/****************************/
/*          Serch           */
/****************************/

var EZF_Search_Instance;
var EZF_Search = Class.create(
{    
    initialize: function(containerClientId, inputFieldClientId, linkToResultPage, options) 
    {   
        this.options = options || {};
        
        this.ContainerClientId = containerClientId;
        this.Container = $(this.ContainerClientId);
        this.InputFieldClientId = inputFieldClientId;
        this.InputField = $(this.InputFieldClientId);
        this.SearchImageUrl = this.options.images.loop;
        this.loadingImageUrl = this.options.images.loader;
        this.LinkToResultImageUrl = this.options.images.search;
        this.LinkToResultPage = linkToResultPage;
        this.SelectedItemIndex = -1; 
        this.LogMessages = new Array();
        this.LogToConsole = true;
        this.ErrorMessage = null;
        this.CategoriesDOM = new Array();
        this.AllElementsDom = new Array();
        
        this.Categories = new Array();
        this.Designers = new Array();
        this.Products = new Array();        
        this.ResultItems = new Array();
              
        this.MaxVisibleSearchResult = 8;
        this.SearchDelayTime = 500; //ms
        this.Cache = null;
        this.Utility = new EZF_Utility();
        
        if(this.InputField != null)
        {
            this.InputFieldOnKeyUpHandler = this.OnInputField_KeyUp.bindAsEventListener(this);
            this.OnDocumentMouseClickHandler = this.OnDocument_MouseClick.bindAsEventListener(this);
        
            Event.observe(this.InputField, "keyup", this.InputFieldOnKeyUpHandler);
            Event.observe(document, "click", this.OnDocumentMouseClickHandler);
        
            //Renderer header, body container and bottom.
            this.EnsureControl(); 
        }
    },
    OnInputField_KeyUp : function(eventArgs)
    {   
        if(this.Utility.IsArrowKey(eventArgs.keyCode))//Up down navigation
        {
            var direction = this.Utility.GetArrowDirection(eventArgs.keyCode);
            if(direction == DirectionEnum.Up || direction == DirectionEnum.Down)
            {
                this.Navigate(this.Utility.GetArrowDirection(eventArgs.keyCode));
            }
            
        }
        else if(this.Utility.IsEnterKey(eventArgs.keyCode))
        {
            if(this.SelectedItemIndex >= 0)
            {
                if(this.AllElementsDom[this.SelectedItemIndex] != null)
                {
                    window.location = this.AllElementsDom[this.SelectedItemIndex].href;
                }
            }
        }
        else //Search
        {
            if(this.InputField.value.length == 0)
            {
                this.Element.style.display = "none";
            }
        
            //See if the user input is in cache. If so use cache value else call server            
            if(this.Cache != null && this.Cache[this.InputField.value] != null)
            {
                this.PerformSearch_Succes(this.Cache[this.InputField.value]);
            }
            else
            {   
                if(this.InputField.value.length > 0 && 
                    (this.Utility.IsNumberKey(eventArgs.keyCode) || 
                    this.Utility.IsLetterKey(eventArgs.keyCode) ||
                    this.Utility.IsAllowedSpecialKey(eventArgs.keyCode)))
                {
                    //Each time user presses key we need to restart the timeout.
                    //We do this to preverent calling the server too often. 
                    //Ideally we wanna call the server when the sentence is complete.
                    //Each keystroke buys the user 500 ms.
                    if(this.TimeOut != null)
                    {
                        clearTimeout (this.TimeOut);
                    }
                    this.TimeOut = setTimeout(function(){ this.OnInputField_KeyUpDelayed()}.bind(this), this.SearchDelayTime);    
                }
            }  
        }
    },
    OnInputField_KeyUpDelayed : function()
    {   
        this.ShowWait();

        this.PerformSearch(this.InputField.value)
        this.StillTyping = false;
    },
    OnDocument_MouseClick : function(eventArgs)
    {   
        var element = Event.element(eventArgs);
        
        if(element == this.InputField || element == this.Element)
        {
            return;
        }
        
        var descendants = $(this.Element).descendants();
        if(descendants.length > 0 && descendants.indexOf(element) == -1)
        {
            this.Element.style.display = "none";
        }
    },
    EnsureControl : function()
    {
        if(this.Element == null)
        {
            this.Element = document.createElement("div");
            this.Element.className = "ezf_intellisearch";

            //Header. Container the top header image.
            this.Header = document.createElement("div");
            this.Header.className = "header";
            
            //Content. This section is populated with resultitems
            this.Content = document.createElement("div");
            this.Content.className = "content";
                        
            //Footer. Contains the bottom image.
            this.Footer = document.createElement("div");
            this.Footer.className = "footer";
            
            this.Element.appendChild(this.Header);
            this.Element.appendChild(this.Content);
            this.Element.appendChild(this.Footer);
            
            
            this.SearchImage = new Image()
            this.SearchImage.className = "searchImage";
            this.SearchImage.src = this.SearchImageUrl;
            this.SearchImage.alt = "Søg";
            this.SearchImage.title = "Søg";
            
            this.Container.appendChild(this.SearchImage);
            
            this.Container.appendChild(this.Element);
        }
    },
    ClearAll: function()
    {
        this.AllElementsDom.clear();
        
        //Remove old dom elements
        this.CategoriesDOM.each(function(element){$(element).remove();});
        
        //Remove old elements 
        this.CategoriesDOM.clear();
        
        if(this.ContentFooter != null)
        {
            $(this.ContentFooter).remove();
            this.ContentFooter = null;
        }
    },
    RenderContent : function()
    {
        this.SelectedItemIndex = -1; 
        this.ClearAll();
    
        //Render designers first
        if(this.Designers != null && this.Designers.length > 0)
        {
            var designerCategory = this.CreateCategory(this.options.localization.txtDesigner, this.Designers);
            this.Content.appendChild(designerCategory);
            this.CategoriesDOM.push(designerCategory);
        }
        
        if(this.Categories != null && this.Categories.length > 0)
        {
            var categoryCategory = this.CreateCategory(this.options.localization.txtCategories, this.Categories);
            this.Content.appendChild(categoryCategory);
            this.CategoriesDOM.push(categoryCategory);
        }  
        
        if(this.Products != null && this.Products.length > 0)
        {
            var productCategory = this.CreateCategory(this.options.localization.txtProducts, this.Products);
            this.Content.appendChild(productCategory);
            this.CategoriesDOM.push(productCategory);
        }       
           
        //Render Footer
        this.ContentFooter = this.CreateContentFooter();
        this.Content.appendChild(this.ContentFooter);
        
        
        //Write to console (FF)
        if(this.LogToConsole)
        {
            this.LogMessages.each(function(element){this.Utility.LogConsole(element)}.bind(this));
        }
    },
    CreateItemProduct : function(itemData)
    {
        var link = document.createElement("a");
        link.className = "item product";
        link.href = itemData.Link;

        var text = document.createElement("div");
        text.className = "text";

        //Text top (designer name & price)
        var textTop = document.createElement("div");
        textTop.className = "textTop";
        
        var header = document.createElement("h3");
        header.innerHTML = itemData.DesignerName;
                
        var bestPrice = document.createElement("div");
        bestPrice.className = "bestprice";
        
        textTop.appendChild(header);
        textTop.appendChild(bestPrice);
        textTop.appendChild(this.Utility.ClearDiv());
        
        //Text bottom (product name & discount)
        var textBottom = document.createElement("div");
        textBottom.className = "textBottom";
        
        var discription = document.createElement("div");
        discription.innerHTML = itemData.Discription;
        
        var productName = document.createElement("div");
        productName.className = "productname";
        
        productName.innerHTML = itemData.ProductName;
        
        /*var productNameValue = document.createElement("span");
        productNameValue.innerHTML = itemData.ProductName;
        productNameValue.className = "productnametext";
        
        productName.appendChild(productNameValue);*/
        
        //Price    
        if(itemData.Price != null)
        {
            bestPrice.innerHTML = itemData.Price.BestPrice.Value + ",-";
            
            if(itemData.Price.HasDicount)
            {
                productName.className = "productname withprice";
                
                var price = document.createElement("span");
                price.className = "scrollerItemprice";
                        
                var discount = 100 - Math.round((itemData.Price.DiscountPrice.Value/itemData.Price.NormalPrice.Value)*100);
                
                var oldPrice = document.createElement("span");   
                oldPrice.className = "oldprice";
                oldPrice.innerHTML = "Før "+itemData.Price.NormalPrice.Value;
                
                var priceDiscount = document.createElement("span");               
                priceDiscount.className = "discount";
                priceDiscount.innerHTML = " " + this.options.localization.txtDiscount + " " + discount + "%";
                
                price.appendChild(oldPrice);
                price.appendChild(priceDiscount);
                
                productName.appendChild(price);
                productName.appendChild(this.Utility.ClearDiv());
            }
        }   
        
        textBottom.appendChild(productName);
        textBottom.appendChild(this.Utility.ClearDiv());
        textBottom.appendChild(discription);
        
        text.appendChild(textTop);
        text.appendChild(textBottom);
    
        //Image
        if(itemData.Image != null)
        {
            var image = new Image();
            image.src = itemData.Image;
            image.alt = itemData.AltAndTitle;
            image.title = itemData.AltAndTitle;
            link.appendChild(image);
        }
        
        this.ItemOnMouseOverHandler = this.OnItem_Mouseover.bindAsEventListener(link);
        this.ItemOnMouseOutHandler = this.OnItem_Mouseout.bindAsEventListener(link);
        
        Event.observe(link, "mouseover", this.ItemOnMouseOverHandler);
        Event.observe(link, "mouseout", this.ItemOnMouseOutHandler);
        
        link.appendChild(text);
        link.appendChild(this.Utility.ClearDiv());
        
        this.AllElementsDom.push(link);
        
        return link;
    },
    CreateItemDesigner : function(itemData)
    {
        var link = document.createElement("a");
        link.className = "item designer";
        link.href = itemData.Link;

        var text = document.createElement("div");
        text.className = "text";
        
        var header = document.createElement("h3");
        header.innerHTML = itemData.ProductName;
        text.appendChild(header);
        
        this.ItemOnMouseOverHandler = this.OnItem_Mouseover.bindAsEventListener(link);
        this.ItemOnMouseOutHandler = this.OnItem_Mouseout.bindAsEventListener(link);
        
        Event.observe(link, "mouseover", this.ItemOnMouseOverHandler);
        Event.observe(link, "mouseout", this.ItemOnMouseOutHandler);
        
        link.appendChild(text);
        link.appendChild(this.Utility.ClearDiv());
        
        this.AllElementsDom.push(link);
        
        return link;
    },
    CreateItem : function(itemData)
    {
        if(itemData.ElementTypeEnum == ByFlouIntelliSearchAjax.SearchResultElementTypeEnum.Designer ||
            itemData.ElementTypeEnum == ByFlouIntelliSearchAjax.SearchResultElementTypeEnum.Category)
        {
            return this.CreateItemDesigner(itemData);
        }
        if(itemData.ElementTypeEnum == ByFlouIntelliSearchAjax.SearchResultElementTypeEnum.Product)
        {
            return this.CreateItemProduct(itemData);
        }
        else
        {
            alert("Der er sket en fejl\r\nCreateItem: Nodetypen er hverken designer eller product.")
        }
    },
    CreateCategory : function(categoryName, itemDataList)
    {
        var category = document.createElement("div");
        
        if(this.CategoriesDOM.length == 0)
        {
             category.className = "category first";
        }
        else
        {
            category.className = "category";
        }
        
        //Create category header
        var categoryHeader = document.createElement("div");
        categoryHeader.className = "categoryHeader";
        
        var categoryHeaderText = document.createElement("h3");
        categoryHeaderText.innerHTML = categoryName;
        
        categoryHeader.appendChild(categoryHeaderText);
        category.appendChild(categoryHeader);
    
        //Create items
        if(itemDataList != null)
        {
            for(var i=0; i < itemDataList.length; i++)
            {
                currentItem = itemDataList[i];
                var item = this.CreateItem(currentItem);
                category.appendChild(item);
            }
        }
        return category;
    }, 
    CreateContentFooter : function()
    {        
        var contentFooter = document.createElement("div");
        contentFooter.className = "contentfooter";
        
        var contentFooterText = document.createElement("span");
        contentFooter.appendChild(contentFooterText);
            
                
        if(this.ResultItems.length > 0)
        {                        
            var linkToResultPage = document.createElement("a");
            linkToResultPage.href = this.LinkToResultPage + "?SearchPhrase="+this.InputField.value;
            linkToResultPage.innerHTML = this.options.localization.txtShowAllSearchResults;
            
            contentFooter.appendChild(linkToResultPage);
        }
        else if(this.ErrorMessage != null)
        {
            contentFooterText.innerHTML = this.ErrorMessage;
            contentFooter.className = "contentfooter center";            
        }
        else
        {
            contentFooterText.innerHTML = this.options.localization.txtNoResults;
            contentFooter.className = "contentfooter center";
        }
        return contentFooter;
    },
    OnItem_Mouseover : function(eventArgs)
    {
        if(!Element.hasClassName(this, "selected"))
        {
            Element.addClassName(this, "selected");
        }
    },
    OnItem_Mouseout : function(eventArgs)
    {
        Element.removeClassName(this, "selected");
    },    
    ShowWait : function()
    {
        this.EnsureWait();
        this.WaitImage.style.display = "block";
        this.SearchImage.style.display = "none";
    },
    HideWait : function()
    {
        if(this.WaitImage != null)
        {
            this.WaitImage.style.display = "none";
            this.SearchImage.style.display = "block";
        }
    },
    Navigate : function(direction)
    {        
        if(direction == DirectionEnum.Down)
        {
            this.SelectedItemIndex = (this.SelectedItemIndex+1)%this.AllElementsDom.length; 
        }
        else if(direction == DirectionEnum.Up)
        {
            if(this.SelectedItemIndex == 0)
            {
                this.SelectedItemIndex = this.AllElementsDom.length-1;
            }
            else
            {
                this.SelectedItemIndex = (this.SelectedItemIndex-1)%this.AllElementsDom.length;  
            }
        }
        if(this.AllElementsDom.length >= this.SelectedItemIndex)
        {
            this.AllElementsDom.each(function(element){element.removeClassName("selected")});
            if(this.AllElementsDom[this.SelectedItemIndex] != null)
            {
                this.AllElementsDom[this.SelectedItemIndex].addClassName("selected");
            }
        }
    },
    EnsureWait : function()
    {
        if(this.WaitImage == null)
        {
            this.WaitImage = new Image();
            this.WaitImage.src = this.loadingImageUrl;
            this.WaitImage.alt = "";
            this.WaitImage.className = "searchspinner";
            
            this.Container.appendChild(this.WaitImage);
        }
    },
    PerformSearch : function(searchPhrase)
    {
        //CallWebserver
        ByFlouIntelliSearchAjax.PerformSearch(searchPhrase, this.PerformSearch_Succes.bind(this));
    },
    PerformSearch_Succes : function(transport)
    {
        var searchKey = transport.request.args["searchKey"];
        if(searchKey == this.InputField.value)
        {
            this.HideWait();
            
            //Save value in client cache
            if(this.Cache == null)
            {
                this.Cache = new Object();
            }
            
            
            if(this.Cache[searchKey] == null)
            {
                this.Cache[searchKey] = transport;
            }
            
            
            this.ResultItems.clear();
            this.Designers.clear();
            this.Products.clear();
            this.Categories.clear();
            this.ErrorMessage = null;
            
            if(transport.value != null)
            {
                if(transport.value.First != null && transport.value.First.length > 0)
                {
                    //This is sorting table!
                    var numberOfElements = Math.min(this.MaxVisibleSearchResult, transport.value.First.length);
                    
                    for(var i=0; i < numberOfElements; i++)
                    {
                        var currentItem = transport.value.First[i];
                
                        if(currentItem.ElementTypeEnum == ByFlouIntelliSearchAjax.SearchResultElementTypeEnum.Designer)
                        {
                            this.Designers.push(currentItem);
                        }
                        if(currentItem.ElementTypeEnum == ByFlouIntelliSearchAjax.SearchResultElementTypeEnum.Product)
                        {
                            this.Products.push(currentItem);
                        }
                        if(currentItem.ElementTypeEnum == ByFlouIntelliSearchAjax.SearchResultElementTypeEnum.Category)
                        {
                            this.Categories.push(currentItem);
                        }
                    }
                    this.ResultItems = transport.value.First.slice();;
                }
                else if(transport.value.Second != null && transport.value.Second != "")
                {
                    this.ErrorMessage = transport.value.Second;
                }
                this.LogMessages = transport.value.Third;
            }
            this.RenderContent();
            this.Element.style.display = "block";
        }
    }
});


/*COMMON*/
function printPopup(url, name)
{
    window.open(url, name,'width=1024, height=768, scrollbars=1');
}

function HookUpContainerCollapser(triggerElementClientId, triggerEventName, controlToCollapseClientId, cssWhenCollapsed)
{
    var triggerElement = $(triggerElementClientId);
    var controlToCollapse = $(controlToCollapseClientId);
    
    if($(triggerElementClientId) == null)
    {
        throw "HookUpContainerCollapser: Could not find trigger element, be sure to use clientids";
    }
    
    if(triggerEventName == null || triggerEventName == "")
    {
        throw "HookUpContainerCollapser: Empty eventname! (mebbe use onClick?)";
    }
    
    if($(triggerElementClientId) == null)
    {
        throw "HookUpContainerCollapser: Could not find control to collapse, be sure to use clientids";
    }
    
    Event.observe(triggerElement, triggerEventName, ContainerCollapser.bindAsEventListener(controlToCollapse, cssWhenCollapsed, triggerElement));
    Event.observe(triggerElement, "mouseover", function(eventArgs){this.style.cursor = 'pointer'}.bindAsEventListener(triggerElement));
}

function ContainerCollapser(eventArgs)
{
    var data = $A(arguments);
    var element = this;
    if($(element) != null)
    {
        if($(element).style.display == "none")
        {
            $(element).show();
        }
        else
        {
            $(element).hide();
        }
        
        $(data[2]).toggleClassName(data[1]);
        
    }
}