﻿
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Class declaration of the Client Side Arrays.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function Article(articleId,name,image,imgPath,zoomImgPath,pricePrefix,variants,labelPos1Visible,labelPos2Visible,labelPos3Visible,labelPos4Visible)
{
    this.ArticleId = articleId;                     
    this.Name = name;                               // Article display name
    this.Img = image;                               // The name of the product/article image
    this.ImgPath = imgPath;                         // the path to the product/article image
    this.ZoomImgPath = zoomImgPath;                 // the path to the product/article zoom image    
    this.PricePrefix = pricePrefix;                 // the prefix before the price (e.g. fr.)
    this.Variants = variants;                       // Variants
    this.LabelPos1Visible= labelPos1Visible;
    this.LabelPos2Visible= labelPos2Visible;
    this.LabelPos3Visible= labelPos3Visible;
    this.LabelPos4Visible= labelPos4Visible;
}

//function Variant(variantId,name,price,isOneClickArticle,isFromPrice,hasAlternatePrice,alternatePrice,isAffectedByDiscount,hasDate,dateDisplay,availability,deliveryStatus,hasSimilarVariants,similarProductsLink,hasDiscountInfoText,discountInfoTextDisplay)
function Variant(variantId,name,price,isOneClickArticle,isFromPrice,hasAlternatePrice,alternatePrice,isAffectedByDiscount,hasDate,dateDisplay,availability,deliveryStatus,hasSimilarVariants,similarProductsLink,hasDiscountInfoText,discountInfoTextDisplay, bookingNo, partpaymentmonth)
{
    this.VariantId = variantId;
    this.Name = name;                                   // the display text of the variant.
    this.Price = price;                                 // string, the current price to display
    this.IsOneClickArticle = isOneClickArticle;         // 1 if IsOneClickArticle else 0
    this.IsFromPrice = isFromPrice;                     // 1 if IsFromPrice else 0
    this.HasAlternatePrice = hasAlternatePrice;         // 1 if HasAlternatePrice else 0
    this.AlternatePrice = alternatePrice;               // string, the formated alternate price string
    this.IsAffectedByDiscount = isAffectedByDiscount;   // 1 if IsAffectedByDiscount else 0
    this.HasDate = hasDate;                             // 1 if HasDate else 0
    this.DateDisplay = dateDisplay;                     // string, the formated date string
    this.Availability = availability;                   // 0: NotApplicable,  1:InStock,  2:NoStock,  3:SoldOut
    this.DeliveryStatus = deliveryStatus;               // string, delivery status
    this.HasSimilarVariants = hasSimilarVariants;       // 0 if nosimilarVariants or if not applicable else 1.                       
    this.SimilarProductsLink = similarProductsLink;     // the link to listpage with similar products.
    this.HasDiscountInfoText = hasDiscountInfoText;     // 1 if HasDiscountInfoText else 0
    this.DiscountInfoTextDisplay = discountInfoTextDisplay; // string, the formated DiscountInfoText string
    //Added: Boris Estrada, Guide Konsult Gbg AB, 2006-10-02 (EL99160).
    this.BookingNo = bookingNo;                         // the VariantActivity's booking no.
    //Added: David Johansson, Sigma Solutions, 2008-05-12 (el99534). {10} PartPaymentMonth
    this.PartPaymentMonth = partpaymentmonth;           //PartPaymentMonth ex. 299kr/mån
}

function MatchSet(pushSetId,pricePrefix,buyText,item)
{    
    this.PushSetId = pushSetId;         // the identity of the PushSet if applicable, else 0.
    this.PricePrefix = pricePrefix;     // string, the prefix before the price (e.g. fr.)
    this.BuyText = buyText;             // string, the text of the buy button.
    this.Item = item;                   // MSItem
}
function MSItem(imgUrl,name,price,link,oneClickProduct,isFromPrice,hasAlternatePrice,alternatePrice,isAffectedByDiscount,hasDate,dateDisplay,articleId)
{
    this.ImgUrl = imgUrl;                               // string, the path to the item image
    this.Name = name;                                   // string, the text to display
    this.Price = price;                                 // string, the formated price string
    this.Link = link;                                   // string, the internal link to DetailPage
    this.OneClickProduct = oneClickProduct;             // 1 if oneClickProduct else 0
    this.IsFromPrice = isFromPrice;                     // 1 if IsFromPrice else 0
    this.HasAlternatePrice = hasAlternatePrice;         // 1 if HasAlternatePrice else 0
    this.AlternatePrice = alternatePrice;               // string, the formated alternate price string
    this.IsAffectedByDiscount = isAffectedByDiscount;   // 1 if IsAffectedByDiscount else 0
    this.HasDate = hasDate;                             // 1 if HasDate else 0
    this.DateDisplay = dateDisplay;                     // string, the formated date string
    this.ArticleId = articleId;                         // the articleId
}


function RenderAvailability()
{
    var articleIndex = document.getElementById('RcnArticleIndex').value;
    var variantIndex = document.getElementById('RcnVariantIndex').value;
    var objAvailability = document.getElementById('RcnAvailability');
    var objAvailabilityInStock = document.getElementById('RcnAvailabilityInStock');
    var objAvailabilityNoStock = document.getElementById('RcnAvailabilityNoStock');
    var objDeliveryStatus = document.getElementById('RcnAvailabilityDeliveryStatus');
    var objRcnAvailabilityLowStock = document.getElementById('RcnAvailabilityLowStock');
    var objAvailabilityInStockAlmostSoldOut = document.getElementById('RcnAvailabilityInStockAlmostSoldOut');
    var objAvailabilityDeliveryAlmostSoldOut = document.getElementById('RcnAvailabilityDeliveryAlmostSoldOut');

    if(articleIndex == '0' || articleIndex == '')
    {
        articleIndex = 0;
    }
      
    if(variantIndex == '0' || variantIndex == '')
    {
        variantIndex = 0;
    }
    
    // Set DeliveryStatus
    if(A[articleIndex].Variants[variantIndex].Availability > 0)
    {
        objAvailability.style.display = 'inline';        
        objAvailabilityInStock.style.display = 'none';
        objAvailabilityNoStock.style.display = 'inline';
    }
    else
    {
        objAvailability.style.display = 'none';
        objRcnAvailabilityLowStock.style.display = 'none'; 
    }
    
    // In Stock
    if(A[articleIndex].Variants[variantIndex].Availability == 1)
    {
        objAvailabilityInStock.style.display = 'inline';
        objAvailabilityNoStock.style.display = 'none';
        objRcnAvailabilityLowStock.style.display = 'none'; 
        objAvailabilityInStockAlmostSoldOut.style.display = 'none';
        objAvailabilityDeliveryAlmostSoldOut.style.display = 'none';       
    }
    
    // No Stock
    if(A[articleIndex].Variants[variantIndex].Availability == 2)
    {
        objDeliveryStatus.innerHTML = A[articleIndex].Variants[variantIndex].DeliveryStatus;
        objAvailabilityInStock.style.display = 'none';
        objAvailabilityNoStock.style.display = 'inline';
        objRcnAvailabilityLowStock.style.display = 'none'; 
        objAvailabilityInStockAlmostSoldOut.style.display = 'none';
        objAvailabilityDeliveryAlmostSoldOut.style.display = 'none';        
    }
    else
    {
        // TODO: What todo, should probably never happen
        objDeliveryStatus.innerHTML = A[articleIndex].Variants[variantIndex].DeliveryStatus;
        objAvailabilityInStock.style.display = 'none';
        objAvailabilityNoStock.style.display = 'inline';
        objRcnAvailabilityLowStock.style.display = 'none'; 
        objAvailabilityInStockAlmostSoldOut.style.display = 'none';
        objAvailabilityDeliveryAlmostSoldOut.style.display = 'none';     
    }
    
    /* Low Stock Warning */
     if(A[articleIndex].Variants[variantIndex].Availability == 4)
    {       
       objAvailabilityInStock.style.display = 'inline';
       objAvailabilityNoStock.style.display = 'none';
       objRcnAvailabilityLowStock.style.display = 'block'; 
       objAvailabilityInStockAlmostSoldOut.style.display = 'inline';
       objAvailabilityDeliveryAlmostSoldOut.style.display = 'none';       
    }
    
     if(A[articleIndex].Variants[variantIndex].Availability == 5)
    {
       objDeliveryStatus.innerHTML = A[articleIndex].Variants[variantIndex].DeliveryStatus;
       objAvailabilityInStock.style.display = 'none';
       objAvailabilityNoStock.style.display = 'inline';
       objRcnAvailabilityLowStock.style.display = 'block';
       objAvailabilityInStockAlmostSoldOut.style.display = 'none';
       objAvailabilityDeliveryAlmostSoldOut.style.display = 'inline';     
    }
}



function RenderArticleDisplay(index)
{
    // if called without parameters then display text from "ViewState"
    if( arguments.length < 1)
        index = document.getElementById('RcnArticleIndex').value;
        
    if (index == '')
        index = 0;
        
    var objArticleDisplay = document.getElementById('RcnArticleDisplay');
    objArticleDisplay.innerHTML = A[index].Name;
}

//Added: Boris Estrada, Guide Konsult Gbg AB, 2006-10-02 (EL99160).
function RenderArticleNo(index)
{
    // if called without parameters then display text from "ViewState"
    if( arguments.length < 1)
        index = document.getElementById('RcnArticleIndex').value;
        
    if (index == '')
        index = 0;
        

    var variantIndex = document.getElementById('RcnVariantIndex').value;
      
    if(variantIndex == '0' || variantIndex == '')
    {
        variantIndex = 0;
    }    
        
    var objArticleDisplay = document.getElementById('RcnArticleNo');
    var objArticleText = document.getElementById('RcnArticleNoText');

    if (A[index].ArticleId != -1 && A[index].Variants[variantIndex].BookingNo != '')
    {
        objArticleText.style.visibility='visible';
        objArticleDisplay.innerHTML = ": " + A[index].Variants[variantIndex].BookingNo;//+ A[index].ArticleId;
    }
    else 
    {
        objArticleText.style.visibility='hidden';
        objArticleDisplay.innerHTML = "";
    }
}

function RenderPriceInfo()
{
    // TODO: Check that the object above exist before rendering...
    var objAlternatePrice = document.getElementById('PCAlternatePrice');
    var objFromPrice = document.getElementById('PCFromPrice');
    var objPrice = document.getElementById('PCPrice');
    //Added: David Johansson, Sigma Solutions, 2008-05-12 (el99534). {10} PartPaymentMonth
    var objPartPaymentMonth = document.getElementById('PCPartPaymentMonth');
    var objNicePrice = document.getElementById('PCNicePrice');
    var objDate = document.getElementById('PCDate');
    var objDiscountInfoText = document.getElementById('PCDiscountInfoText');
    
    // Get article- and variant index from the hidden state controls.
    var articleIndex = document.getElementById('RcnArticleIndex').value;
    var variantIndex = document.getElementById('RcnVariantIndex').value;
        
    if(articleIndex == '0' || articleIndex == '')
        articleIndex = 0;
      
    if(variantIndex == '0' || variantIndex == '')
        variantIndex = 0;
           
    
    // Alternate price
    
    if( A[articleIndex].Variants[variantIndex].HasAlternatePrice == 1 )
    {
        objAlternatePrice.innerHTML = '(' + A[articleIndex].Variants[variantIndex].AlternatePrice + ')';
        objAlternatePrice.style.display = 'inline';
    }
    else
    {
        objAlternatePrice.style.display = 'none';
    }
    
    // Current Price
    objPrice.innerHTML = A[articleIndex].Variants[variantIndex].Price;
    objNicePrice.innerHTML = A[articleIndex].Variants[variantIndex].Price;
    objFromPrice.innerHTML = A[articleIndex].PricePrefix;
    if( A[articleIndex].Variants[variantIndex].IsAffectedByDiscount == 1 && A[articleIndex].Variants[variantIndex].HasAlternatePrice == 1)
    {
        objNicePrice.style.display = 'inline';
        objPrice.style.display = 'none';
    }
    else
    {
        objNicePrice.style.display = 'none';
        objPrice.style.display = 'inline';
    }
    
    // Show PricePrefix
    if( A[articleIndex].Variants[variantIndex].IsFromPrice == 1)
        objFromPrice.style.display = 'inline';
    else
        objFromPrice.style.display = 'none';

    // Show date.
    if( A[articleIndex].Variants[variantIndex].HasDate == 1)
    {
        objDate.innerHTML = A[articleIndex].Variants[variantIndex].DateDisplay;
        objDate.style.display = 'inline';
    }
    else
    {
        objDate.style.display = 'none';
    }

    // Info text.
    if( A[articleIndex].Variants[variantIndex].HasDiscountInfoText == 1)
    {
        objDiscountInfoText.innerHTML = A[articleIndex].Variants[variantIndex].DiscountInfoTextDisplay;
        objDiscountInfoText.style.display = 'inline';
    }
    else
    {
        objDiscountInfoText.style.display = 'none';
    }
    
    //Show the calculated PartPaymentMonth price
    objPartPaymentMonth.innerHTML = A[articleIndex].Variants[variantIndex].PartPaymentMonth;
}

/************************************************************************
RenderMatchSet: Renders HTML to the client side MatchSet control
 parameters     index:  Identifies the index of the MatchSet Array
                ctrlId: (optional) The element id of the div to render.
************************************************************************/
function RenderMatchSet(index, ctrlId )
{
    // If this function is called with MatchSet array index only.
    if( arguments.length < 2)
        ctrlId = 'MatchSetSpan';
    
    // Check that we have an element to render to.
    if ( !document.getElementById(ctrlId) )
        return;
        
    var span = document.getElementById(ctrlId);
    
    // Check that we have a MatchSet to render.
    if ( M.length <= index )
        return;
        
    // Check that MatchSet for this index exist.
    if( M[index].Item.length <= 0 )
    {
        // TODO: Should we then släcka redan renderade matcningar?
        //document.getElementById('MatchSetHeaderDiv').style.display = 'none';
        //div.style.display = 'none';
        return;
    }
    
    // Ok, lets render the HTML.
    var s = '';
    var price = '';
    var comDate = '';
    var buyButton = '';
    //s = '<div style="float:left;"><img src="/images/generic/listpage__match_leftline.gif" alt="" border="0" /></div>';
    for(i=0; i<M[index].Item.length; i++)
    {
        s+= '<span class="prod_match'+(i+1)+'"><a href="' + M[index].Item[i].Link + '"><img src="' + M[index].Item[i].ImgUrl + '"  alt="" /></a></span>'

    }
    for(i=0; i<M[index].Item.length; i++)
    {
        // Price communication
        if( M[index].Item[i].IsFromPrice == 1 )
            price = '<span >' +  M[index].PricePrefix + '</span>';
        price += '<span class="product_price" style="color:Black">' + M[index].Item[i].Price + '</span>';

        if( M[index].Item[i].HasAlternatePrice == 1 )
                price = '<span class="product_price">' + M[index].Item[i].Price + '</span><br/><span class="">(' + M[index].Item[i].AlternatePrice + ')</span>';
        
        if( M[index].Item[i].HasDate == 1 )
            comDate += '<span class="MSDate">' + M[index].Item[i].DateDisplay + '</span>';
            
        // OneClickProduct, Render a "buy button".
        if( M[index].Item[i].OneClickProduct == 1 )
        {
            var lbtId = 'FooBar';
            var lbtArg = M[index].Item[i].ArticleId;
            
            // Business Logic. Lets generate a postback event and send the articleId as argument
            buyButton = '<span class=""><img src="//media.redcatsnordic.com/jotex/images/generic/RightRaquo.gif" alt="" border="0" />&nbsp;<a href="#" onclick=javascript:__doPostBack("' + lbtId + '",' + lbtArg + ');>' + M[index].BuyText + '</a></span>';
        }
        
        s+= '<span class="prod_match_l'+(i+1)+'"><span class="match_text">' + M[index].Item[i].Name + '<br />'+price+'<br />'+comDate+'<br/>'+buyButton+'</span></span>'
    }    

    span.innerHTML = s;
    //document.getElementById('MatchSetHeaderDiv').style.display = 'inline';
    //div.style.display = 'inline';
}

function RenderProductImage(index, htmlAnchorId, htmlImageId )
{
    
    if(arguments.length < 3)
        htmlImageId = 'RcnProductImage';
        
    if(arguments.length < 2)
        htmlAnchorId = 'RcnProductImageLink';
        
    if(arguments.length < 1)
        index = 0;
    
    // Check that we have an element to render to.
    if (!document.getElementById(htmlImageId))
    {
        alert('RcnProductImage not found');
        return;
    }   
    var objImg = document.getElementById(htmlImageId);
    
    if (!document.getElementById(htmlAnchorId))
    {
        alert('RcnProductImageLink not found');
        return;
    }    
    var objLink = document.getElementById(htmlAnchorId);
            
    // set image src
    objImg.src = A[index].ImgPath;

    // set a href to pop zoom window
    objLink.href = PopupZoomUrl(A[index].Img);
    var zoomExt = Sys.UI.Behavior.getBehaviorByName(objImg,  'ZoomImageBehavior');
    if(zoomExt)
    {
        zoomExt.set_zoomImageSrc(A[index].ZoomImgPath);
        zoomExt.set_onClickScript("PopupZoom('" + A[index].Img + "');");
    }
    
    // hide promotion labels
    var labelPos1 = getLabelPos("1");
    var labelPos2 = getLabelPos("2");
    var labelPos3 = getLabelPos("3");
    var labelPos4 = getLabelPos("4");
    if(index > 0)
    {
        if(labelPos1 != null)
        {
        
            if(A[index].LabelPos1Visible)
            {
                labelPos1.style.display = '';
            }else{
                labelPos1.style.display = 'none';
            }
        }
        
        if(labelPos2 != null)
        {
        
            if(A[index].LabelPos2Visible)
            {
                labelPos2.style.display = '';
            }else{
                labelPos2.style.display = 'none';
            }
        }
        
        if(labelPos3 != null)
        {
        
            if(A[index].LabelPos3Visible)
            {
                labelPos3.style.display = '';
            }else{
                labelPos3.style.display = 'none';
            }
        }
        
        if(labelPos4 != null)
        {
        
            if(A[index].LabelPos4Visible)
            {
                labelPos4.style.display = '';
            }else{
                labelPos4.style.display = 'none';
            }
        }
    }
    else
    {
    }
}

function PopupZoom(imgSrc){
    url = '/misc/ProductZoom.aspx?ImageSource=' + imgSrc;
    window.open(url);
}

function getLabelPos(number)
{
    var objects = document.getElementsByTagName('img');
    for(i=0;i<objects.length;i++)
    {
        if(objects[i].id.indexOf('imgLabelPos' + number) > 0)
        {
            return objects[i];
        }
    }
    return null;
}

function RenderProductZoomLink(index, htmlAnchorId)
{
    if(arguments.length < 2)
        htmlAnchorId = 'RcnProductZoom';
        
    if(arguments.length < 1)
    {
        index = document.getElementById('RcnArticleIndex').value;
        if(index == '')
            index = 0;
    }
    
    if(!document.getElementById(htmlAnchorId))
    {
        alert('element ' + htmlAnchorId + ' not found.');
        return; 
    }
    var objLink = document.getElementById(htmlAnchorId);
    objLink.href = PopupZoomUrl(A[index].Img);
}

function PopupZoomUrl(imgSrc)
{
    if(arguments.length < 1)
    {
        alert('missing variable imgSrc in function PopupZoomUrl(imgSrc)');
        return;
    }
    
    return url = '/misc/ProductZoom.aspx?ImageSource=' + imgSrc;
}

/************************************************************************
PopulateVariants:   Populates the variant select.
    ctrl:   The id of the HTMLSelect control.
    index:  The article index.
************************************************************************/
function PopulateVariants(ctrl, index)
{
    if( document.getElementById(ctrl) )
    {
        var ddl = document.getElementById(ctrl);
        var selectedText = '';
        var variantIndex = 0;
        var findOption = false;
                        
        // delete existing items
        for(i = ddl.options.length; i>0; i--)
            ddl.options[i] = null;
           
        // Add the variants. Observe that VariantIndex 0 represents the article when no variant is selected (i.e. do not render index = 0 to the selectbox options)
        for(j=1; j<A[index].Variants.length; j++)
            addOption(ddl,A[index].Variants[j].Name,A[index].Variants[j].VariantId);
            
        if(ddl.options.length == 2)
        {
            variantIndex = 1;
            selectedText = ddl.options[1].text; 
            SaveVariantIndexToViewState(1);          
        }
        // Try to get previously selected item (variant).
        var previousSelection = ddl.selectedIndex > 0 ? ddl.selectedIndex : (document.getElementById('RcnVariantIndex').value > 0 ? document.getElementById('RcnVariantIndex').value : 0) 
        if(previousSelection > 0)
        {
            if(ddl.options[previousSelection]!=null)
            {
                findOption = true;
                selectedText = ddl.options[previousSelection].text;
            }
            else
            {
                selectedText = ddl.options[0].text;
            }
        }
            
        if(findOption == true)
        {            
            for(z=0; z<ddl.options.length; z++)
            {
                if(ddl.options[z].text == selectedText)
                    variantIndex = z;
            }            
        }
        
        // Set selected item.
        ddl.selectedIndex = variantIndex;
        
        // Finally save current variant index to the client side "viewState" (hidden input)
        SaveVariantIndexToViewState(variantIndex);
        
        // Returns the selected variantIndex
        return variantIndex;
    }
}
/************************************************************************
addOption:   Adds an OPTION to a HTMLSelect control.
    selectbox:  The HTMLSelect element.
    text:       Sets the text.
    value:      Sets the value.
************************************************************************/
function addOption(selectbox,text,value )
{
    var optn = document.createElement("OPTION");
    optn.text = text;
    optn.value = value;
    selectbox.options.add(optn);
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions to set focus on the article images.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**************************************************************************
HideImageBorders:   Removes the border from all article images
***************************************************************************/
function HideImageBorders()
{
    for(i=0;i<=A.length;i++)
    {
        if(document.getElementById('Border' + i))
        {
            document.getElementById('Border' + i).className="";
        }
    }
}
/*************************************************************************************
RenderArticleImageBorder:   Renders a border arround the article image with this index
**************************************************************************************/
function RenderArticleImageBorder(index)
{
    HideImageBorders();
    if(document.getElementById('Border' + index))
    {
        document.getElementById('Border' + index).className="product_smallthumb_active";
    }
}
/**************************************************************************
GetArticleIndexOnArticleId: Returns article index on articleId
***************************************************************************/
function GetArticleIndexOnArticleId(articleId)
{
    var index = 0;
    for(i=0; i<A.length; i++)
    {
        if( A[i].ArticleId == articleId)
            index = i;
    }
    return index;
}
/**************************************************************************
GetArticleIdOnIndex:    Returns articleId on article index
***************************************************************************/
function GetArticleIdOnIndex(articleIndex)
{
    return A[articleIndex].ArticleId;
}
/**************************************************************************
GetVariantIdOnIndex:    Returns variantId on article- index and variant index
***************************************************************************/
function GetVariantIdOnIndex(articleIndex, variantIndex)
{
    return A[articleIndex].Variants[variantIndex].VariantId;
}

/**************************************************************************
SaveArticleIndexToViewState:    Sets current article index and articleId
                                to the hidden input html input fields in order
                                to maintain state between postbacks.
                                
    parameters:     index:      The zero-based index of the selected article.
***************************************************************************/
function SaveArticleIndexToViewState(index)
{
    if(!document.getElementById('RcnArticleIndex'))
        return;
    document.getElementById('RcnArticleIndex').value = index;
    
    // Save articleId to hidden field.
    if(!document.getElementById('RcnArticleId'))
    {
        alert('Missing element RcnArticleId');
        return
    }
    document.getElementById('RcnArticleId').value = GetArticleIdOnIndex(index);
}

/**************************************************************************
SaveVariantIndexToViewState:    Sets current variant index and variantId
                                to the hidden input html input fields in order
                                to maintain state between postbacks.
                                
    parameters:     index:      The zero-based index of the selected variant.
***************************************************************************/
function SaveVariantIndexToViewState(index)
{
    if(!document.getElementById('RcnVariantIndex'))
        return;
    document.getElementById('RcnVariantIndex').value = index;
    
    // Save variantId to hidden field.
    if(!document.getElementById('RcnVariantId'))
    {
        alert('Missing element RcnVariantId');
        return
    }
    document.getElementById('RcnVariantId').value = GetVariantIdOnIndex( document.getElementById('RcnArticleIndex').value, index);
}

/***********************************************************************************
SaveVariantIdToViewState:   Sets variantId to the hidden html input field RcnVariantId.
    variantId:     The variantId to write to the hidden field
***********************************************************************************/
function SaveVariantIdToViewState(variantId)
{
    if(!document.getElementById('RcnVariantId'))
        return;
    document.getElementById('RcnVariantId').value = variantId;
}

/***********************************************************************************
SetSelectedIndex:   Method to set the selected index of a HTMLSelect control
    ctrlId:     The element id of the control
    index:      The index to set as selected.
***********************************************************************************/
function SetSelectedIndex(ctrlId, index)
{    
    if(!document.getElementById(ctrlId))
        return;
                    
    var ctrl = document.getElementById(ctrlId);
    
    if(ctrl.options.length < index)
        return;
    
    ctrl.selectedIndex = index;
}


///////////////////////////////////////////////////////////////////////////////
// RcnSelect    Test class attach to <select>
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnSelect, RcnElementEventPublisherSubscriber);

function RcnSelect(id)
{
    if ( arguments.length )
        this.InitInstance(id);
}

RcnSelect.prototype.InitInstance = function(id)
{
    RcnSelect.baseClass.InitInstance.call(this, id);
    if( this.Element() )
    {
        this.Element().onchange = this.OnSelectChangeHandler;
    }
}

RcnSelect.prototype.OnSelectChangeHandler = function()
{   
    RcnClientFx.GetRcnObject(this).SelectChange();
}

RcnSelect.prototype.SelectChange = function()
{
    alert(this.Element().selectedIndex);
    this.TrigEvent(new RcnArticleEvent(this, this.Element().selectedIndex));
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// RcnArticleImages     Class attach to the article image container. 
//                      <div><div1><img1/></div1> ... <divN><imgN/></divN></div>
//      Register javascript as: var rcnArticleImages = new RcnArticleImages("divId", 0, new RcnArticleImage("img1", 1), new RcnArticleImage("img2", 2),...,new RcnArticleImage("imgN", N));
//    
//  Parameters
//          id:                 The element id of the outer <div> (Not implemented)
//          articleIndex:       The selected article index (Not implemented)
//          argument(2 ... N):  RcnArticleImage. syntax: new RcnArticleImage("imgId", articleIndex)
/////////////////////////////////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnArticleImages, RcnElementEventPublisherSubscriber);

function RcnArticleImages(id, articleIndex)
{
    if ( arguments.length )
        this.InitInstance.apply(this, arguments);
}

RcnArticleImages.prototype.InitInstance = function(id, articleIndex)
{
    RcnArticleImages.baseClass.InitInstance.call(this, id);

    for(i=2; i<=arguments.length-1; i++)
    {
        this.AttachEvent(new RcnArticleEvent(null, 0), arguments[i]);
        arguments[i].AttachEvent(new RcnArticleEvent, this); 
    }
      
    RcnArticleImages.prototype.HandleEvent = function(eventObj)
    {
        this.TrigEvent(eventObj);
    }    
}

///////////////////////////////////////////////////////////////////////////////
// RcnArticleImage:     Class attach to the Article Image
//          id:             The element id of the HTMLImage <img>.
//          articleIndex:   The article index representing this image.
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnArticleImage, RcnElementEventPublisherSubscriber);

function RcnArticleImage(id, articleIndex)
{
    if ( arguments.length )
        this.InitInstance(id, articleIndex);
}

RcnArticleImage.prototype.InitInstance = function(id, articleIndex)
{
    RcnArticleImage.baseClass.InitInstance.call(this, id);
    this.articleImageElement = document.getElementById(id);
    this.articleImageIndex = articleIndex;
    
    if( this.articleImageElement )
    {
        // onClick
        this.articleImageElement.onclick = this.OnClickHandler;
        
        // onMouseOver
        this.articleImageElement.onmouseover = this.OnMouseOverHandler;
        
        // onMouseOut
        this.articleImageElement.onmouseout = this.OnMouseOutHandler;
    }
}

RcnArticleImage.prototype.OnClickHandler = function()
{
    RcnClientFx.GetRcnObject(this).ArticleImageClick();
}
RcnArticleImage.prototype.ArticleImageClick = function()
{   
    // Store the articleIndex
    SaveArticleIndexToViewState(this.articleImageIndex);

    // Trigger the RcnArticleEvent
    this.TrigEvent(new RcnArticleEvent(this, this.articleImageIndex));
}

RcnArticleImage.prototype.OnMouseOverHandler = function()
{
    RcnClientFx.GetRcnObject(this).ArticleImageOnMouseOver();
}
RcnArticleImage.prototype.ArticleImageOnMouseOver = function()
{   
    // Trigger the RcnArticleOnMouseOverEvent
    this.TrigEvent(new RcnArticleOnMouseOverEvent(this, this.articleImageIndex));
}

RcnArticleImage.prototype.OnMouseOutHandler = function()
{
    RcnClientFx.GetRcnObject(this).ArticleImageOnMouseOut();
}
RcnArticleImage.prototype.ArticleImageOnMouseOut = function()
{   
    this.TrigEvent(new RcnArticleOnMouseOutEvent(this, this.articleImageIndex));
}

RcnArticleImage.prototype.HandleEvent = function(eventObj)
{   
    if(eventObj.ClassName() == "RcnArticleEvent")
    {
        if(eventObj.ArticleIndex() == this.articleImageIndex)
        {
            // Call function that renders a border round the selected article image.
            RenderArticleImageBorder(this.articleImageIndex);
        }
    }    
}

///////////////////////////////////////////////////////////////////////////////
// RcnSelector  Class attach to <div><select1/><select2/></div>
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnSelector, RcnElementEventPublisherSubscriber);

function RcnSelector(id, idArticle, idVariant)
{
    if ( arguments.length )
        this.InitInstance(id, idArticle, idVariant);
}

RcnSelector.prototype.InitInstance = function(id, idArticle, idVariant)
{
    RcnSelector.baseClass.InitInstance.call(this, id);
    this.articleElement = document.getElementById(idArticle);
    this.variantElement = document.getElementById(idVariant);    
    
    if( this.articleElement )
    {
        RcnClientFx.AttachRcnObject(this.articleElement, this);
        this.articleElement.onchange = this.OnArticleSelectChangeHandler
    }
    
    if( this.variantElement )
    {
        RcnClientFx.AttachRcnObject(this.variantElement, this);
        this.variantElement.onchange = this.OnVariantSelectChangeHandler
    }
}

RcnSelector.prototype.OnArticleSelectChangeHandler = function()
{   
    RcnClientFx.GetRcnObject(this).ArticleSelectChange();
}

RcnSelector.prototype.OnVariantSelectChangeHandler = function()
{   
    RcnClientFx.GetRcnObject(this).VariantSelectChange();
}

RcnSelector.prototype.ArticleSelectChange = function()
{   

    // Store the articleIndex
    SaveArticleIndexToViewState(this.articleElement.selectedIndex);
    
    // Mark the article image
    RenderArticleImageBorder(this.articleElement.selectedIndex);
    
    // Populate variants and get the new variantId, trigger events.
    // But, only if the variant select box is redered to page.
    if( this.variantElement )
    {   
        var selectedVariantIndex = PopulateVariants(this.variantElement.id, this.articleElement.selectedIndex);
        
        // Trigger events
        this.TrigEvent(new RcnVariantEvent(this, selectedVariantIndex));
        this.TrigEvent(new RcnArticleVariantEvent(this, this.articleElement.selectedIndex, selectedVariantIndex));
    }
    else
    {
        var oldVariantIndex = document.getElementById('RcnVariantIndex').value;        
        var selectedVariantIndex = 0;
        if(this.articleElement.selectedIndex > 0)
            selectedVariantIndex = 1;       
                 
        // Store the variantIndex
        SaveVariantIndexToViewState(selectedVariantIndex);
        
        if(oldVariantIndex != selectedVariantIndex)
        {
            // Trigger events
            this.TrigEvent(new RcnVariantEvent(this, selectedVariantIndex));
            this.TrigEvent(new RcnArticleVariantEvent(this, this.articleElement.selectedIndex, selectedVariantIndex));
        }
    }
    
    // Trigger events.
    this.TrigEvent(new RcnArticleEvent(this, this.articleElement.selectedIndex));    
    
}

RcnSelector.prototype.VariantSelectChange = function()
{
    // Store the variantIndex
    SaveVariantIndexToViewState(this.variantElement.selectedIndex);
    
    this.TrigEvent(new RcnVariantEvent(this, this.variantElement.selectedIndex));    
    this.TrigEvent(new RcnArticleVariantEvent(this, this.articleElement.selectedIndex, this.variantElement.selectedIndex));    
}

RcnSelector.prototype.HandleEvent = function(eventObj)
{
    // I only let my RcnSelector attach to the ArticleImages and not to itself. Therefore some "events are handled" in the ArticleSelectChange function above...
    if(eventObj.ClassName() == 'RcnArticleEvent')
    {
        
        // The user has clicked on an article image.
        
        // Change selected index of the article HTMLSelect        
        SetSelectedIndex(this.articleElement.id, eventObj.ArticleIndex());
        
        // Re-populate Variants, if the variant select box exist
        if( this.variantElement )
        {
            var selectedVariantIndex = PopulateVariants(this.variantElement.id, eventObj.ArticleIndex());
             // Trigger events
            this.TrigEvent(new RcnVariantEvent(this, selectedVariantIndex));
            this.TrigEvent(new RcnArticleVariantEvent(this, this.articleElement.selectedIndex, selectedVariantIndex));
        }
        else
        {
            var oldVariantIndex = document.getElementById('RcnVariantIndex').value;        
            var selectedVariantIndex = 0;
            if(this.articleElement.selectedIndex > 0)
                selectedVariantIndex = 1;       
                     
            // Store the variantIndex
            SaveVariantIndexToViewState(selectedVariantIndex);
            
            if(oldVariantIndex != selectedVariantIndex)
            {
                // Trigger events
                this.TrigEvent(new RcnVariantEvent(this, selectedVariantIndex));
                this.TrigEvent(new RcnArticleVariantEvent(this, this.articleElement.selectedIndex, selectedVariantIndex));
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////////////
// RcnDivMatchSet    Test class attach to the MatchSet <div>
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnDivMatchSet, RcnElementEventSubscriber);

function RcnDivMatchSet(id)
{
    if ( arguments.length )
        this.InitInstance(id);
}

RcnDivMatchSet.prototype.InitInstance = function(id)
{
    RcnDivMatchSet.baseClass.InitInstance.call(this, id);
}

RcnDivMatchSet.prototype.HandleEvent = function(eventObj)
{
    if(eventObj.ClassName() == "RcnArticleEvent")
    {
        RenderMatchSet( eventObj.ArticleIndex(), this.Element().id );
    }    
}

///////////////////////////////////////////////////////////////////////////////
// RcnArticleDisplay
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnArticleDisplay, RcnElementEventSubscriber);

function RcnArticleDisplay(id)
{
    if ( arguments.length )
        this.InitInstance(id);
}

RcnArticleDisplay.prototype.InitInstance = function(id)
{
    RcnArticleDisplay.baseClass.InitInstance.call(this, id);
}

RcnArticleDisplay.prototype.HandleEvent = function(eventObj)
{
    if(eventObj.ClassName() == "RcnArticleEvent")
    {
        RenderArticleDisplay(eventObj.ArticleIndex());
        RenderArticleNo(eventObj.ArticleIndex());
    }
    
    if(eventObj.ClassName() == "RcnArticleOnMouseOverEvent")
    {
        RenderArticleDisplay(eventObj.ArticleIndex());
    }
    
    if(eventObj.ClassName() == "RcnArticleOnMouseOutEvent")
    {
        // call RenderArticleDisplay() without parameters to reset text.
        RenderArticleDisplay();
    }
    
    //Added: Boris Estrada, Guide Konsult Gbg AB, 2006-10-03 (EL99160).
    if(eventObj.ClassName() == "RcnArticleVariantEvent")
    {
        RenderArticleNo(eventObj.ArticleIndex());
    }
}

///////////////////////////////////////////////////////////////////////////////
// RcnProductImage      Class attach to the RcnProductImage control <a><img /></a>
// parameters:          htmlAnchorId: the element id of <a> surrounding the <img> product image.
//                      htmlImageId:  the element id of <img> the product image.
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnProductImage, RcnElementEventSubscriber);

function RcnProductImage(htmlAnchorId, htmlImageId)
{
    if ( arguments.length )
        this.InitInstance(htmlAnchorId, htmlImageId);
}

RcnProductImage.prototype.InitInstance = function(htmlAnchorId, htmlImageId)
{
    RcnProductImage.baseClass.InitInstance.call(this, htmlAnchorId, htmlImageId);
    this.htmlAnchorElement = document.getElementById(htmlAnchorId);
    this.htmlImageElement = document.getElementById(htmlImageId);
}

RcnProductImage.prototype.HandleEvent = function(eventObj)
{
    if(eventObj.ClassName() == "RcnArticleEvent")
    {
        RenderProductImage(eventObj.ArticleIndex(), this.htmlAnchorElement.id, this.htmlImageElement.id);
    }    
}

///////////////////////////////////////////////////////////////////////////////
// RcnProductZoom       Class attach to the RcnProductZoom control <a>
// parameters:          htmlAnchorId: the element id of <a>
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnProductZoom, RcnElementEventSubscriber);

function RcnProductZoom(htmlAnchorId)
{
    if ( arguments.length )
        this.InitInstance(htmlAnchorId);
}

RcnProductZoom.prototype.InitInstance = function(htmlAnchorId)
{
    RcnProductZoom.baseClass.InitInstance.call(this, htmlAnchorId);
    this.htmlAnchorElement = document.getElementById(htmlAnchorId);
}

RcnProductZoom.prototype.HandleEvent = function(eventObj)
{
    if(eventObj.ClassName() == "RcnArticleEvent")
    {
        RenderProductZoomLink(eventObj.ArticleIndex(), this.htmlAnchorElement.id);
    }    
}

///////////////////////////////////////////////////////////////////////////////
// RcnPriceCommunicator  Class attach to the Price Communicator on DetailPage   
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnPriceCommunicator, RcnElementEventSubscriber);

function RcnPriceCommunicator(id)
{
    if ( arguments.length )
        this.InitInstance(id);
}

RcnPriceCommunicator.prototype.InitInstance = function(id)
{
    RcnPriceCommunicator.baseClass.InitInstance.call(this, id);    
}

RcnPriceCommunicator.prototype.HandleEvent = function(eventObj)
{
    if(eventObj.ClassName() == "RcnArticleEvent")
    {
        RenderPriceInfo();
    }
    
    if(eventObj.ClassName() == "RcnVariantEvent")
    {
        RenderPriceInfo();
    }
    
    if(eventObj.ClassName() == "RcnArticleVariantEvent")
    {        
        RenderPriceInfo();    
    }
}

///////////////////////////////////////////////////////////////////////////////
// RcnAvailability  
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnAvailability, RcnElementEventSubscriber);

function RcnAvailability(id)
{
    if ( arguments.length )
        this.InitInstance(id);
}

RcnAvailability.prototype.InitInstance = function(id)
{
    RcnAvailability.baseClass.InitInstance.call(this, id);    
}

RcnAvailability.prototype.HandleEvent = function(eventObj)
{
    if(eventObj.ClassName() == "RcnArticleEvent")
    {
        RenderAvailability();
    }
    
    if(eventObj.ClassName() == "RcnVariantEvent")
    {
        RenderAvailability();
    }
    
    if(eventObj.ClassName() == "RcnArticleVariantEvent")
    {
        RenderAvailability();   
    }
}


/** Event Section ***********************************************************/

///////////////////////////////////////////////////////////////////////////////
// RcnArticleEvent    
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnArticleEvent, RcnEvent);

function RcnArticleEvent(src, articleIndex)
{
    if ( arguments.length )
        this.InitInstance(src, articleIndex);
}

RcnArticleEvent.prototype.InitInstance = function(src, articleIndex)
{
    RcnArticleEvent.baseClass.InitInstance.call(this, src);
    this.articleIndex = articleIndex;
}

RcnArticleEvent.prototype.ArticleIndex = function()
{
    //set
    if( arguments.length )
        this.articleIndex = arguments[0];
        
    //get
    return this.articleIndex;
}

///////////////////////////////////////////////////////////////////////////////
// RcnVariantEvent    
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnVariantEvent, RcnEvent);

function RcnVariantEvent(src, variantIndex)
{
    if ( arguments.length )
        this.InitInstance(src, variantIndex);
}

RcnVariantEvent.prototype.InitInstance = function(src, variantIndex)
{
    RcnVariantEvent.baseClass.InitInstance.call(this, src);
    this.variantIndex = variantIndex;
}

RcnVariantEvent.prototype.VariantIndex = function()
{
    //set
    if( arguments.length )
        this.variantIndex = arguments[0];
        
    //get
    return this.variantIndex;
}

///////////////////////////////////////////////////////////////////////////////
// RcnArticleVariantEvent    
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnArticleVariantEvent, RcnEvent);

function RcnArticleVariantEvent(src, articleIndex, variantIndex)
{
    if ( arguments.length )
        this.InitInstance(src, articleIndex, variantIndex);
}

RcnArticleVariantEvent.prototype.InitInstance = function(src, articleIndex, variantIndex)
{
    RcnArticleVariantEvent.baseClass.InitInstance.call(this, src);
    this.articleIndex = articleIndex;
    this.variantIndex = variantIndex;
}

RcnArticleVariantEvent.prototype.ArticleIndex = function()
{
    //set
    if( arguments.length )
        this.articleIndex = arguments[0];
        
    //get
    return this.articleIndex;
}

RcnArticleVariantEvent.prototype.VariantIndex = function()
{
    //set
    if( arguments.length )
        this.variantIndex = arguments[0];
        
    //get
    return this.variantIndex;
}

///////////////////////////////////////////////////////////////////////////////
// RcnArticleOnMouseOverEvent    
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnArticleOnMouseOverEvent, RcnEvent);

function RcnArticleOnMouseOverEvent(src, articleIndex)
{
    if ( arguments.length )
        this.InitInstance(src, articleIndex);
}

RcnArticleOnMouseOverEvent.prototype.InitInstance = function(src, articleIndex)
{
    RcnArticleOnMouseOverEvent.baseClass.InitInstance.call(this, src);
    this.articleIndex = articleIndex;
}

RcnArticleOnMouseOverEvent.prototype.ArticleIndex = function()
{
    //set
    if( arguments.length )
        this.articleIndex = arguments[0];
        
    //get
    return this.articleIndex;
}

///////////////////////////////////////////////////////////////////////////////
// RcnArticleOnMouseOutEvent    
///////////////////////////////////////////////////////////////////////////////
RcnClientFx.CopyPrototype(RcnArticleOnMouseOutEvent, RcnEvent);

function RcnArticleOnMouseOutEvent(src, articleIndex)
{
    if ( arguments.length )
        this.InitInstance(src, articleIndex);
}

RcnArticleOnMouseOutEvent.prototype.InitInstance = function(src, articleIndex)
{
    RcnArticleOnMouseOutEvent.baseClass.InitInstance.call(this, src);
    this.articleIndex = articleIndex;
}

RcnArticleOnMouseOutEvent.prototype.ArticleIndex = function()
{
    //set
    if( arguments.length )
        this.articleIndex = arguments[0];
        
    //get
    return this.articleIndex;
}

function ChangeToAlternateProductImage(fullpath, image, zoomImgPath)
{
    if(!rcnProductImage)
        return false;
    var objImg = rcnProductImage.htmlImageElement;
    objImg.src = fullpath;
    var zoomExt = Sys.UI.Behavior.getBehaviorByName(objImg,  'ZoomImageBehavior');
    if(zoomExt)
    {
        zoomExt.set_onClickScript("PopupZoom('" + image + "');");
        zoomExt.set_zoomImageSrc(zoomImgPath);
    }
   
    document.getElementById('RcnProductImageLink').href = PopupZoomUrl(image);
    
    if(document.getElementById('RcnProductZoom'))
        document.getElementById('RcnProductZoom').href = PopupZoomUrl(image);
    
    var maxlbls = 4;
    var index = 1;
    for(index = 1; index < (maxlbls + 1); index++)
    {
        var lbl = getLabelPos(index);
        if(lbl != null)
        {
            lbl.style.display = '';
        }
    }
    
    return true;
}

function InitAndSetVariant(articleSelectId, variantSelectId)
{
    var selArt = document.getElementById(articleSelectId);
    var selVar = document.getElementById(variantSelectId);
    
    if(selArt != null && selVar != null)
    {
        // If an article is selected and variants are not initialized
        if(selArt.selectedIndex != 0 && selVar.options.length <= 1)
        {
            // store variantindex from hidden control because it gets 
            // overwritten in the onchange event
            var variantIndex = document.getElementById('RcnVariantIndex').value;
            
            // trigger onchange event to init variant dropdown
            selArt.onchange();
            if(selVar.options.length == 2)
                variantIndex = 1;
            selVar.selectedIndex = variantIndex;
        }
    }
}
