﻿
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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 == '') {

        // If there's only one variant (i.e. no size, first element's empty)
        if (A[articleIndex].Variants.length == 2) {

            variantIndex = 1;
            SaveVariantIndexToViewState(1);

        } else
            variantIndex = 0;

    }

    // Set DeliveryStatus
    if (A[articleIndex].Variants[variantIndex].Availability > 0) {
        objAvailability.style.display = 'block';
        objAvailabilityInStock.style.display = 'none';
        objAvailabilityNoStock.style.display = 'block';
    }
    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 = 'block';
        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 = 'block';
    }
}



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;

    RenderArticleImageBorder(index);
}

//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);
            $(".sizeVariantLabel").hide();
            $(".sizeVariantLabelSelected").show();
            
        }
        // 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;
    }
}

/************************************************************************
PopulateVariantList:   Populates the variant html list.
index:  The article index.
************************************************************************/
function PopulateVariantList(index) {
    $("#chosenSize").empty();
    $("#sizeOptions").empty();
    var strHtml = "";
    for (j = 1; j < A[index].Variants.length; j++) {
    
        if (A[index].Variants.length == 2) {
            strHtml += "<div onclick=\"setSize(this);\" title='" + A[index].Variants[j].Name + "' variant='" + A[index].Variants[j].VariantId + "' class=\"sizeButton selected\">" + A[index].Variants[j].Name + "</div>";
            $("#chosenSize").text(A[index].Variants[j].Name); 
            SaveVariantIndexToViewState(1);
        } else {
        if ($(".variantSelectorDropdown :selected").text() == A[index].Variants[j].Name) {
            strHtml += "<div onclick=\"setSize(this);\" title='" + A[index].Variants[j].Name + "' variant='" + A[index].Variants[j].VariantId + "' class=\"sizeButton selected\">" + A[index].Variants[j].Name + "</div>";
            $("#chosenSize").text(A[index].Variants[j].Name);
        }else{
            strHtml += "<div onclick=\"setSize(this);\" title='" + A[index].Variants[j].Name + "' variant='" + A[index].Variants[j].VariantId + "' class=\"sizeButton\">" + A[index].Variants[j].Name + "</div>";
            }
        }
    }
    strHtml += "<div class='clearBoth'></div>";
    $("#sizeOptions").html(strHtml);
}



/************************************************************************
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 = "articleImageSelect";
        }
    }
}
/*************************************************************************************
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) {

        PopulateVariantList(this.articleElement.selectedIndex);
        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) {

            PopulateVariantList(eventObj.ArticleIndex());
            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;
        }
    }
}

