// © 20-20 Technologie Inc. 2015
// All Rights Reserved
// version 2.2.2
//Last updated Date 19-09-2019

var pafDoc = null;
var fDiv = null;
var relDoc = null;
var oDiv = null;
var selOs = [];
var selOsNode;
var focusN = "";
var styleMap = new KeyMap("");
var priceMap = new KeyMap("");
var styleIncMap = new KeyMap("");
var exclusions = new Matches();
var excShown = [];
var optCount = [];
var allFeature = [];
var manFeOpt = [];
var assoFeature = [];
var addinfo = "";
var CompactAddInfo = false;
var singleOpt = [];
var selF = "#d3d3d3";
var prodName = "Global.GSV";
var spSize = 67;
var DefaultOpt = [];
var FeatureGroup = [];
var PmMandFeature = [];
var stFeature = [];
var preFeCount = 0;
var fOrder = [];
var AllFeatures = [];
var FGfeatures = [];
var relProducts = [];
var hiddenFeature = [];
var Feat = [];
var isRepFeat = [];
var featureOption = [];
var tempfeatureOption = [];

function flush() {
    fDiv = null;
    oDiv = null;
    pafDoc = null;
    relDoc = null;
    styleIncMap = null;
    styleMap = null;
    priceMap = null;
    selOs = null;
    exclusions = null;
    selOsNode = null;
    focusN = null;
    excShown = null;
    manFeOpt = null;
    assoFeature = null;
    addinfo = null;
    singleOpt = null;
    DefaultOpt = null;
    fOrder = null;
}
window.load = function (file) {
    try {
        pafDoc = new ActiveXObject("Microsoft.XMLDOM");
        pafDoc.async = "false";
        pafDoc.load(file);
        loadInfos();
        countOpts();
        loadFeatures();
        getRelatedProducts();
        selectMandOptions();
        if (location.search != null) {
            loadSelectedOptions(location.search.substr(1));
        }
        setIsPrintable();
        isDisplay3Pane();
        selectDefaultOpt();
        getPreSelFeCount();
        document.getElementById("centerFrame2").style.display = "none";
        if (CompactAddInfo == false) addinfo = "<br>&nbsp;</br>";
    }
    catch (err) {
        alert(err.message);
    }

}

function getRelatedProducts() {
    var product = pafDoc.selectNodes('//Product[@code="' + prodName + '"]/RelatedProductRef');
    var code = "";
    for (var i = 0; i < product.length; i++) {
        var code = product[i].getAttribute("code");
        relProducts.push([code]);
        var OptState = product[i].selectNodes("OptionState");
        var fCode = "";
        var OCode = "";
        var count = 1;
        for (var j = 0; j < OptState.length; j++) {
            fCode = OptState[j].getAttribute("featureCode");
            OCode = OptState[j].getAttribute("optionCode");
            relProducts[i][count] = fCode;
            count = count + 1;
            relProducts[i][count] = OCode;
            count = count + 1;
        }
    }
}

function getPreSelFeCount() {
    preFeCount = PmMandFeature.length;
    for (var i = 0; i < selOs.length; i++) {
        for (var j = 0; j < PmMandFeature.length; j++) {
            if (selOs[i][0] == PmMandFeature[j][0]) {
                if (PmMandFeature[j][1] == false) {
                    PmMandFeature[j][1] = true;
                    preFeCount--;
                    break;
                }
            }
        }
    }
}

function selectMandOptions() {
    var manAutofeature = pafDoc.selectNodes('//Feature/FeatureSubset[@isOptional="false"]');
    var fetureCode = "";
    var count = 0;
    var parentFeature = "";
    var options = "";
    var optCode = "";
    if (manAutofeature.length > 0) {
        for (var k = 0; k < manAutofeature.length; k++) {
            fetureCode = manAutofeature[k].getAttribute("code");
            for (var i = 0; i < optCount.length; i++) {
                if (optCount[i][0] == fetureCode) {
                    count = optCount[i][1];
                    if (count == 1) {
                        parentFeature = manAutofeature[k].parentNode.getAttribute("code");
                        options = pafDoc.selectNodes('//Feature/FeatureSubset[@code="' + fetureCode + '"]/OptionRef');
                        optCode = options[0].getAttribute("code");
                        assoFeature.push([fetureCode, parentFeature]);
                        manFeOpt.push([parentFeature, optCode]);
                        pushSelection(parentFeature, optCode, false);
                    }
                }
            }
        }
        refreshSelectedOptions();
    }
}

function selectDefaultOpt() {
    var found = false;
    if (DefaultOpt.length > 0) {
        for (var i = 0; i < DefaultOpt.length; i++) {
            found = false;
            for (var j = 0; j < selOs.length; j++) {
                if (DefaultOpt[i][0] == selOs[j][0]) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                pushSelection(DefaultOpt[i][0], DefaultOpt[i][1], false);
            }
        }
    }
    refreshSelectedOptions();
}

function setIsPrintable() {
    var manFeature = pafDoc.selectNodes('//Feature');
    var FecustomData = "";
    var feacustomData = "";
    var varGSV = "";
    var isPrintable = "";
    var FeatureNode = "";
    for (var k = 0; k < manFeature.length; k++) {
        FecustomData = manFeature[k].selectSingleNode("CustomData");
        if (FecustomData != null) {
            feacustomData = getXML(FecustomData.text);
            varGSV = feacustomData.selectSingleNode("//GSV");
            if (varGSV != null) {
                isPrintable = varGSV.getAttribute("isPrintable");
                if (isPrintable == "false") {
                    FeatureNode = manFeature[k].getAttribute("code");
                    document.getElementById(FeatureNode).isPrintable = "false";
                }
            }
        }
    }
}

function loadInfos() {
    if (document.getElementById("manuflogo") == null) {
        document.getElementById("manuf").innerHTML = pafDoc.selectSingleNode("//Company").getAttribute("code");
    }
}

function loadFeatureGroup() {
    var featureGroups = pafDoc.selectNodes("//FeatureGroup");
    for (var fid = 0; fid < featureGroups.length; fid++) {
        var desc = featureGroups[fid].selectSingleNode("DisplayName").text;
        var featRef = featureGroups[fid].selectNodes("FeatureRef");
        var code = featureGroups[fid].getAttribute("code");
        var FG = pafDoc.selectNodes('//Product[@code="' + prodName + '"]/FeatureGroupRef[@code="' + code + '"]');
        if (FG.length == 0) alert("PAF.xml is not valid: FeatureGroups display Order is not Exist in PAF.xml");
        var FGOrder = FG[0].getAttribute("displayOrder");
        if (FGOrder == null) FGOrder = fid;
        AllFeatures.push([code, FGOrder, "FeatureGroup", desc]);
        var features = [];
        for (var j = 0; j < featRef.length; j++) {
            var fcode = featRef[j].getAttribute("code");
            var fsub = pafDoc.selectNodes('//Product[@code="' + prodName + '"]/FeatureSubsetRef[@featureCode="' + fcode + '"]');
            if (fsub.length == 0) {
                hiddenFeature.push(fcode);
                continue;
            }
            var displayord = fsub[0].getAttribute("displayOrder");
            features.push([fcode, displayord]);
            FGfeatures.push(fcode);
        }
        var sortedFe = sortMultiDimArray(features);
        FeatureGroup.push([code, sortedFe, desc]);
    }
}

function sortMultiDimArray(array) {
    var temp;
    for (var i = 0; i < array.length; i++) {
        for (var j = i + 1; j < array.length; j++) {
            if (Number(array[i][1]) > Number(array[j][1])) {
                temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
    return array;
}

function loadFeatures() {
    loadFeatureGroup();
    var content = "";
    var type = "";
    var feCount = 1;
    var features = pafDoc.selectNodes("//Feature");
    for (var i = 0; i < features.length; i++) {
        tempOptioncode = []
        var id = features[i].getAttribute("code");
        var desc = features[i].selectSingleNode("DisplayName").text;
        // create dictionary of feature and list of option
        var options = features[i].selectNodes("Option");
        for (var optCount = 0; optCount < options.length; optCount++) {
            var optcode = options[optCount].getAttribute("code");
            tempOptioncode.push(optcode);
        }
        tempfeatureOption.push([id, tempOptioncode]);
        // dictionary of feature and List of option
        allFeature.push([id, desc]);
        var featSubsCode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + id + '"]');
        if (featSubsCode != null)
            continue;
        var isFG = false;
        for (var ir = 0; ir < FGfeatures.length; ir++) {
            if (FGfeatures[ir] == id) {
                isFG = true;
                break;
            }
        }

        if (isFG) continue;
        var fsub = pafDoc.selectNodes('//Product[@code="' + prodName + '"]/FeatureSubsetRef[@featureCode="' + id + '"]');
        if (fsub.length == 0) {
            hiddenFeature.push(id);
            continue;
        }
        var displayord = fsub[0].getAttribute("displayOrder");
        AllFeatures.push([id, displayord, "Feature", desc]);
    }
    var aFeature = sortMultiDimArray(AllFeatures);
    for (var j = 0; j < aFeature.length; j++) {
        if (aFeature[j][2] == "FeatureGroup") {
            content += '<div class="feature" id="' + aFeature[j][0] + '" loaded="no" feature="' + aFeature[j][0] + '" desc="' + aFeature[j][3] + '" > ' + aFeature[j][3] + '</div>';
            var features = [];
            for (var fg = 0; fg < FeatureGroup.length; fg++) {
                if (FeatureGroup[fg][0] == aFeature[j][0]) {
                    features = FeatureGroup[fg][1];
                    break;
                }
            }
            for (var fCount = 0; fCount < features.length; fCount++) {
                var feature = pafDoc.selectNodes('//Feature[@code="' + features[fCount][0] + '"]');
                if (feature.length > 0) {
                    var desc = feature[0].selectSingleNode("DisplayName").text;
                    if (features[fCount][1] <= 10) {
                        PmMandFeature.push([features[fCount][0], false])
                        type = "mFeature";
                    } else {
                        stFeature.push(features[fCount][0]);
                        type = "sFeature";
                    }
                    Feat.push(features[fCount][0]);
                    fOrder.push([features[fCount][0], type, feCount]);
                    content += '<div class="ChildFeature" disabled type="' + type + '" order="' + feCount + '" isPrintable="true" id="' + features[fCount][0] + '" loaded="no" feature="' + features[fCount][0] + '" desc="' + desc + '" status="0" cn="ChildFeature" cni="childFeatureInvert" focus="0" onmouseover=setFocus(this,"1"); onmouseout=setFocus(this,"0"); onclick=selectFeature(this,"0");>' + desc + '</div>';
                    feCount++;
                }
            }
        } else {
            if (aFeature[j][1] <= 10) {
                PmMandFeature.push([aFeature[j][0], false]);
                type = "mFeature";
            } else {
                stFeature.push(aFeature[j][0]);
                type = "sFeature";
            }
            Feat.push(aFeature[j][0]);
            fOrder.push([aFeature[j][0], type, feCount]);
            content += '<div class="feature" disabled  type="' + type + '" order="' + feCount + '" isPrintable="true" id="' + aFeature[j][0] + '" loaded="no" feature="' + aFeature[j][0] + '" desc="' + aFeature[j][3] + '" status="0" cn="feature" cni="featureInvert" focus="0" onmouseover=setFocus(this,"1"); onmouseout=setFocus(this,"0"); onclick=selectFeature(this,"0");>' + aFeature[j][3] + '</div>';
            feCount++;
        }
    }
    fDiv.innerHTML = content;
    for (var mF = 0; mF < PmMandFeature.length; mF++) {
        document.getElementById(PmMandFeature[mF][0]).disabled = false;
    }
    if (PmMandFeature.length == 0) {
        for (var f = 0; f < Feat.length; f++) {
            document.getElementById(Feat[f]).disabled = false;
        }
    }
    hideExclusions();
}

function isDisplay3Pane() {
    var isimg = false;
    var feats = pafDoc.selectNodes('//Feature');
    for (var i = 0; i < feats.length; i++) {
        var icount = feats[i].selectNodes('Option/Multimedia[@type="LargeImage"]');
        isimg = false;
        if (icount.length > 0) {
            singleOpt.push(feats[i].getAttribute("code"));
            isimg = true;
        }
        var featSubsCode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + feats[i].getAttribute("code") + '"]');
        if (featSubsCode != null) {
            if (isimg) {
                var fea = featSubsCode.parentNode.parentNode.getAttribute("code");
                singleOpt.push(fea);
            }
        }
    }
}

function countOpts() {
    var feats = pafDoc.selectNodes('//Feature/FeatureSubset');
    for (var i = 0; i < feats.length; i++) {
        // var icount = feats[i].parentNode.selectNodes('Option/Multimedia[@type="LargeImage"]');
        var defOpt = feats[i].selectNodes('OptionRef[@isDefault="true"]');
        if (defOpt.length > 0) {
            DefaultOpt.push([feats[i].getAttribute("code"), defOpt[0].getAttribute("code")])
        }
        var isEndRepetition = feats[i].getAttribute("isRepeatable");
        if (isEndRepetition == "true") {
            isRepFeat.push(feats[i].getAttribute("code"));
        }
        if (feats[i].getAttribute("isOptional") == "true")
            continue;
        var opts = feats[i].selectNodes('OptionRef');
        var desc = feats[i].parentNode.selectSingleNode("DisplayName").text;
        optCount.push([feats[i].getAttribute("code"), opts.length, 0, desc]);
    }
}

function countExclusions(mode) {
    var addedFeats = 0;
    for (var i = 0; i < optCount.length; i++) {
        optCount[i][2] = 0;
    }

    for (var i = 0; i < exclusions.matches.length; i++) {
        var feat = exclusions.matches[i][0].key.split(";")[0];
        for (var j = 0; j < optCount.length; j++) {
            if (optCount[j][0] == feat) {
                optCount[j][2] += 1;
            }
        }
    }

    for (var j = 0; j < optCount.length; j++) {
        // todo: also do a check if all options are excluded, also exclude the parent node	
        if (optCount[j][1] - optCount[j][2] == 1) {
            var feat = pafDoc.selectSingleNode('//Feature/FeatureSubset[@code="' + optCount[j][0] + '"]');
            var opts = feat.selectNodes('OptionRef');
            var opt = "";
            var sfeat = "";
            var sopt = "";
            for (var k = 0; k < opts.length && sfeat == ""; k++) {
                opt = opts[k].getAttribute("code");
                var excluded = false;
                sfeat = optCount[j][0];
                sopt = opt;
                for (var x = 0; x < exclusions.matches.length; x++) {
                    var excl = exclusions.matches[x][0].key.split(";");
                    if (optCount[j][0] == excl[0] && opt == excl[1]) {
                        excluded = true;
                        found = false;
                        sfeat = "";
                        sopt = "";
                        break;
                    }
                }
            }
            if (sfeat != "") {
                var cCount = selOs.length;
                if (sopt.indexOf(".O") == -1) {
                    pushSelection(sfeat, sopt, mode);
                }
                if (selOs.length > cCount) {
                    var node = document.getElementById(sfeat);
                    isPremManFeature(node);
                    addedFeats++;
                }

            }
        }
    }

    if (addedFeats > 0) {
        processExclusions(mode);
    }
}

function loadSelectedOptions(opstring) {
    var fcount = 0;
    var options = opstring.split("&");
    var WSoption = "";
    for (var i = 0; i < options.length; i++) {
        var option = options[i].split("=");
        switch (i) {
            case 0:
                feature = "8810000";
                break;
            case 1:
                feature = "8820000";
                break;
            case 2:
                feature = "8830000";
                break;
            case 3:
                feature = "8840000";
                break;
            case 4:
                feature = "8250000";
                break;
            case 5:
                feature = "8260000";
                break;
            case 6:
                feature = "8270000";
                break;
            case 7:
                feature = "8280000";
                break;
        }
        if (option[1] == null)
            return;
        var optionstack = option[1].split("|");
        for (var j = 0; j < optionstack.length; j++) {
            var fNode = feature;
            var changeF = false;
            if (optionstack[j] != "") {
                var matches = pafDoc.selectNodes('//Feature/FeatureSubset/OptionRef[@code="' + optionstack[j] + '"]');
                for (var k = 0; k < matches.length; k++) {
                    var featNodeCode = matches[k].parentNode.getAttribute("code");

                    if (featNodeCode == feature)
                        break;

                    var fNodeflag = false;
                    for (var fcode = 0; fcode < matches.length; fcode++) {
                        var fnCode = matches[fcode].parentNode.getAttribute("code");
                        if (fnCode == feature) {
                            fNodeflag = true;
                            break;
                        }
                    }
                    if (fNodeflag) break;

                    var featSubsCode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + featNodeCode + '"]');
                    if (featSubsCode == null) {
                        for (var fs = 0; fs < allFeature.length; fs++) {
                            if (featNodeCode == allFeature[fs][0]) {
                                feature = featNodeCode;
                                changeF = true;
                                break;
                            }
                        }
                    }

                    while (featSubsCode != null) {
                        if (feature == featSubsCode.parentNode.parentNode.getAttribute("code")) {
                            feature = featNodeCode;
                            changeF = true;
                            break;
                        } else {
                            featSubsCode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + featSubsCode.parentNode.parentNode.getAttribute("code") + '"]');
                        }
                    }
                    if (changeF) break;
                    if (matches.length == 1) {
                        feature = featNodeCode;
                        changeF = true;
                        break;
                    }
                }
                var isProd = false;
                isProd = findRelProdComb(optionstack[j]);
                if (!isProd) {
                    var tempOpt = feature + "." + optionstack[j];
                    isProd = findRelProdComb(tempOpt);
                }
                if (!isProd) {
                    pushSelection(feature, optionstack[j], false);
                }
                fcount++;
                if (changeF) {
                    feature = fNode;
                    changeF = false;
                }
            }
        }
    }

    clearFeatExclusions();
    processExclusions(false);
    refreshSelectedOptions();
    if (fcount != 0) {
        for (var k = 0; k < stFeature.length; k++) {
            document.getElementById(stFeature[k]).disabled = false;
        }
    }
}

function findRelProdComb(Option) {
    var isProd = false;
    for (var arp = 0; arp < relProducts.length; arp++) {
        if (relProducts[arp][0] == Option) {
            for (var iarp = 1; iarp < relProducts[arp].length; iarp++) {
                var iFeature = relProducts[arp][iarp];
                iarp = iarp + 1;
                var iOption = relProducts[arp][iarp];
                pushSelection(iFeature, iOption, false);
                isProd = true;
            }
            break;
        }
    }
    return isProd;
}

function removeOpt(feature, option) {
    for (var i = 0; i < selOs.length; i++) {
        if (selOs[i][0] == feature && selOs[i][1] == option) {
            return selOs[i].splice(i, 1);
        }
    }
    return null;
}

function contains(array, item) {
    for (var i = 0; i < array.length; i++) {
        if (array[i] == item) return true
    }
    return false;
}


function containsOpt(list, opt) {
    for (var i = 0; i < list.length; i++) {
        if (list[i][0] == opt[0] && list[i][1] == opt[1]) return true;
    }
    return false;
}

function findAutoTriggers(feature, option) {
    // for each option selected, unselect it, see if specified option is still automatically selected
    // if not, this option is one of the triggers. Put back the selected option in the list. Repeat for each option. 
    var triggers = [];
    if (getSelected(feature, option) == null) {
        return triggers;
    }
    var processedOptions = [];
    for (var i = 0; i < selOs.length; i++) {
        var temp = selOs[i];
        if (containsOpt(processedOptions, temp)) continue;
        processedOptions.push(temp);
        if (!temp[3]) {
            unselectOption(temp[0], temp[1]);
            if (getSelected(feature, option) == null) {
                triggers.push(temp);
            }
            pushSelection(temp[0], temp[1], temp[3]);
            processExclusions(true);
            i = 0;
        }
    }
    refreshSelectedOptions();
    return triggers;
}

function loadOptions(feature) {
    var content = '<div class="optiondiv" id="' + feature + ';options">';
    var options = pafDoc.selectNodes('//Feature/FeatureSubset[@code="' + feature + '"]/OptionRef');
    optImgSize = 0;
    for (var i = 0; i < options.length; i++) {
        if (options[i].getAttribute("isEndingRepetition") != null && options[i].getAttribute("isEndingRepetition") == "true")
            continue;
        //var optCode = options[i].getAttribute("code");
        content += addOption(options[i], feature, i);
    }
    content += '</div>';
    oDiv.innerHTML += content;
    hideExclusions();
}

function loadExclusions(feature, option) {
    // var inclusionCode = [];
    var exclFlag = new Flag("exclude");
    var restrictions = pafDoc.selectNodes('//Restriction/Combination/OptionRef[@featureCode="' + feature + '"][@optionCode="' + option + '"]');
    for (var i = 0; i < restrictions.length; i++) {
        var combination = restrictions[i].parentNode.parentNode.selectNodes("Combination");
        var type = combination[0].getAttribute("type");
        var keys = [];
        var keyNs = restrictions[i].parentNode.selectNodes("OptionRef");
        if (type == "false") //exclusion
        {
            for (var j = 0; j < keyNs.length; j++) {
                keys.push(new Key(keyNs[j].getAttribute("featureCode") + ";" + keyNs[j].getAttribute("optionCode"), exclFlag));
            }
            styleMap.addKey(keys, 0);
        } else // inclusion
        {
            for (var j = 0; j < keyNs.length; j++) {
                keys.push(new Key(keyNs[j].getAttribute("featureCode") + ";" + keyNs[j].getAttribute("optionCode"), exclFlag));
            }
            styleIncMap.addKey(keys, 0);
        }
    }
}

function loadPricesMatches() {
    for (var i = 0; i < selOs.length; i++) {
        var keys = pafDoc.selectNodes('//PriceRuleDetail/Key[@codeRef="' + selOs[i][1] + '"]');
        for (var j = 0; j < keys.length; j++) {
            var children = keys[j].parentNode.selectNodes('Key');
            var cKeys = [];
            for (var k = 0; k < children.length; k++) {
                var feat = children[k].parentNode.parentNode.selectNodes('KeySource')[k].getAttribute("codeRef");
                cKeys.push(new Key(feat + ";" + children[k].getAttribute("codeRef"), keys[j].parentNode.selectSingleNode("Value").text));
            }
            priceMap.addKey(cKeys, 0);
        }
    }
}

function addOption(option, featurecode, optCnt) {
    var optioncode = option.getAttribute("code");
    var callback = option.selectSingleNode("FeatureSubsetRef") != null ? "selectSubF" : "selectOption";
    option = pafDoc.selectSingleNode('//Feature[@code="' + featurecode + '"]/Option[@code="' + optioncode + '"]');
    var cDN = option.selectSingleNode("CustomData");
    if (cDN != null) var customData = getXML(cDN.text);
    if (customData != null) var reckeynode = customData.selectSingleNode("//RECKEY");
    var reckey = "";
    if (reckeynode != null) {
        reckey = reckeynode.getAttribute("code");
    }
    var className = "option";
    var status = "0";
    for (var i = 0; i < exclusions.matches.length; i++) {
        if (featurecode + ';' + optioncode == exclusions.matches[i][0].key) {
            status = "3";
            className = "optionExcluded";
        }
    }


    if (getSelected(featurecode, optioncode) != null) {
        status = "2";
        className = "optionSelect";
    }
    var imageN = option.selectSingleNode("Multimedia");
    var imagetext = "";
    var optname = "optname1";
    if (imageN != null) {
        var id = featurecode + ";optImg" + optCnt;
        imagetext += '<img src="..\\' + imageN.text + '" id="' + id + '" ></img>';
        className += " grid1";
    } else {
        className += " grid3";
        optname = "optname3";
    }
    return '<div class="' + className + '" id="' + featurecode + ';' + optioncode + '" feature="' + featurecode + '" option="' + optioncode + '" reckey="' + reckey + '" status=' + status + ' cn="option" cni="optionInvert" cns="optionSelect" cne="optionExcluded" sel="no" focus="0" onmouseover=optMouseOver(this,"1"); onmouseout=setFocus(this,"0"); onclick=' + callback + '(this);>' + imagetext + '<div class="' + optname + '">' + option.selectSingleNode("DisplayName").text + '</div></div>';
}

function optMouseOver(node, status) {
    setFocus(node, "1");
    showLargeDisplay(node.feature, node.option);
}

function getExclMatches(optionset, matches) {
    styleMap.getKeys(optionset, matches, 0);
}

function getInclMatches(optionset, matches) {
    styleIncMap.getKeys(optionset, matches, 0);
}

function refreshSelectedOptions() {
    var features = document.getElementById("features");
    for (var i = 0; i < features.childNodes.length; i++) {
        if (features.childNodes[i].cn == "selectedOption") {
            features.removeChild(features.childNodes[i]);
            i--;
        }
    }
    for (var i = 0; i < selOs.length; i++) {
        var oNode = document.getElementById(selOs[i][0] + ";" + selOs[i][1]);
        if (oNode != null)
            setStatus(oNode, "2");
        if (pafDoc.selectSingleNode('//Feature/FeatureSubset[@code="' + selOs[i][0] + '"]/OptionRef[@code="' + selOs[i][1] + '"]/FeatureSubsetRef') != null) {
            continue;
        }
        var optionImage = null;
        var isrcN = pafDoc.selectSingleNode('//Feature/Option[@code="' + selOs[i][1] + '"]/Multimedia')
        var isrcN = pafDoc.selectSingleNode('//Feature[@code="' + selOs[i][0] + '"]/Option[@code="' + selOs[i][1] + '"]/Multimedia')
        if (isrcN != null) {
            isrc = "..\\" + isrcN.text;
            optionImage = document.createElement("image");
            optionImage.src = isrc;
            optionImage.className = "selectedOptionImage";
        }
        var deleteButton = document.createElement("image");
        deleteButton.src = "Delete.png";
        deleteButton.className = "deleteButton";
        deleteButton.setAttribute("feature", selOs[i][0]);
        deleteButton.setAttribute("option", selOs[i][1]);
        deleteButton.onclick = function () {
            for (var i = 0; i < manFeOpt.length; i++) {
                if (this.feature == manFeOpt[i][0] && this.option == manFeOpt[i][1]) {
                    refreshSelectedOptions();
                    return;
                }
            }
            unselectOptionNode(this);
        };
        var child = document.createElement("div");
        child.className = "selectedOption";
        child.cn = "selectedOption";
        child.cni = "selectedOptionInvert";
        child.id = "f;" + selOs[i][0] + ";" + selOs[i][1];
        child.feature = selOs[i][0];
        child.option = selOs[i][1];
        child.parent = selOs[i][2];
        child.status = "0";
        child.focus = "0";
        child.onmouseover = function () {
            setFocus(this, "1");
        };
        child.onmouseout = function () {
            setFocus(this, "0");
        };
        child.onclick = function () {
            selectParentFromOption(this)
        };
        var text = document.createElement("div");
        text.className = "selOT";
        text.innerHTML = selOs[i][1] + " : " + pafDoc.selectSingleNode('//Feature[@code="' + selOs[i][0] + '"]/Option[@code="' + selOs[i][1] + '"]/DisplayName').text;
        if (optionImage != null)
            child.appendChild(optionImage);
        child.appendChild(text);
        child.appendChild(deleteButton);
        var nextfeature = document.getElementById(selOs[i][0]);
        var subF = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + selOs[i][0] + '"]');
        while (subF != null) {
            nextfeature = document.getElementById(subF.parentNode.parentNode.getAttribute("code"));
            subF = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + subF.parentNode.parentNode.getAttribute("code") + '"]');
        }
        while (nextfeature != null) {
            nextfeature = nextfeature.nextSibling;
            if (nextfeature != null && nextfeature.className == "feature")
                break;
            if (nextfeature != null && nextfeature.className == "ChildFeature")
                break;
        }
        if (nextfeature != null) {
            features.insertBefore(child, nextfeature);
        } else {
            features.appendChild(child);
        }
    }
}

function unselectOptionNode(node) {
    var oNode = document.getElementById(node.feature + ";" + node.option);
    var removed = unselectOption(node.feature, node.option);
    if (oNode != null && removed) setStatus(oNode, "0");
    clearFeatExclusions();
    refreshSelectedOptions();
    var tCount = preFeCount;
    var flag = false;
    var isrep = false;
    for (var i = 0; i < PmMandFeature.length; i++) {
        if (node.feature == PmMandFeature[i][0]) {
            for (var ir = 0; ir < isRepFeat.length; ir++) {
                if (node.feature == isRepFeat[ir]) {
                    for (var ik = 0; ik < selOs.length; ik++) {
                        if (node.feature == selOs[ik][0]) {
                            isrep = true;
                            break;
                        }
                    }
                    break;
                }
            }
            if (isrep == false) {
                preFeCount++;
                PmMandFeature[i][1] = false;
                flag = true;
            }
            break;
        }
    }
    if (tCount >= 0 && flag == true) {
        for (var k = 0; k < stFeature.length; k++) {
            document.getElementById(stFeature[k]).disabled = true;
        }
    }
    selectFeature(document.getElementById(node.feature), "0");
}

function unselectOption(feature, option) {
    var found = false;
    for (var i = 0; i < selOs.length; i++) {
        if (selOs[i][0] == feature && selOs[i][1] == option) {
            feature = selOs[i][0];
            selOs.splice(i, 1);
            found = true;
            break;
        }
    }
    purgeSelOs();
    processExclusions(true);
    return found;
}

function setFocus(node, focus) {
    clearFeatExclusions();
    var fnode = document.getElementById(focusN);
    if (fnode != null) {
        fnode.focus = "0";
        switchColors(fnode);
    }
    node.focus = focus;
    switchColors(node);
    focusN = node.id;
    showExclusions(node);
}

function setStatus(node, status) {
    if (node == null)
        return;
    switch (status) {
        case "0":
            node.status = "0";
            break;
        case "2":
            node.status = "2";
            break;
        case "3":
            node.status = "3";
            break;
    }
    switchColors(node);
}

function selectParentFromOption(node) {
    if (document.getElementById("initialimg") != null)
        document.getElementById("initialimg").style.display = "none";
    if (node.parent != null && node.parent != "") {
        var fNode = document.getElementById(node.parent);
        if (fNode == null) {
            var parent;
            var tempParent = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + node.parent + '.O"]').parentNode.getAttribute("code");
            parent = tempParent;
            while (tempParent != null) {
                if (pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + tempParent + '.O"]') != null) {
                    var tempFeature = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + tempParent + '.O"]').parentNode.getAttribute("code");
                }
                else {
                    break;
                }
                tempParent = tempFeature;
                if (tempFeature != null) {
                    parent = tempParent;
                }
            }
            var fNode = document.getElementById(parent);
            if (fNode.disabled == false) {
                selectFeature(fNode, "1");
                selFetureDisplay(fNode, "1");
            }
        }
        if (fNode.disabled == false) {
            loadOptions(node.parent);
            var parent = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + node.feature + '.O"]').parentNode.getAttribute("code");
            loadOptions(parent);
            var fNode = document.getElementById(parent + ";" + node.feature + ".O");
            selectSubF(fNode);
            selFetureDisplay(fNode, "1");
        }
    } else {
        var fNode = document.getElementById(node.feature);
        if (fNode.disabled == false) {
            selectFeature(fNode, "1");
            selFetureDisplay(fNode, "1");
        }
    }
}

function getSelected(feature, option) {
    for (var i = 0; i < selOs.length; i++) {
        if (selOs[i][0] == feature && selOs[i][1] == option)
            return selOs[i];
    }
    return null;
}

function findCommonParent(feature1, feature2) {
    var parent1 = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + feature1 + '"]');
    while (parent1 != null) {
        var parent2 = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + feature2 + '"]');
        while (parent2 != null) {
            if (parent1.parentNode.parentNode.getAttribute("code") == parent2.parentNode.parentNode.getAttribute("code")) {
                return parent1.parentNode.parentNode.getAttribute("code");
            }
            parent2 = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + parent2.parentNode.parentNode.getAttribute("code") + '"]');
        }
        parent1 = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + parent1.parentNode.parentNode.getAttribute("code") + '"]');
    }
    return "";
}

function pushSelection(feature, option, auto) {
    if (assoFeature.length > 0) {
        for (var asFeCount = 0; asFeCount < assoFeature.length; asFeCount++) {
            if (assoFeature[asFeCount][0] == feature) {
                feature = assoFeature[asFeCount][1];
                break;
            }
        }
    }
    var selOpt = getSelected(feature, option);
    if (selOpt != null) {
        if (!auto) {
            selOpt[3] = false;
        }
        return;
    }
    if (!validateOverride())
        return;
    loadExclusions(feature, option);
    var repeatable = pafDoc.selectSingleNode('//Feature/FeatureSubset[@code="' + feature + '"]').getAttribute("isRepeatable") == "true" ? true : false;
    var sub = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + feature + '"]');
    if (sub != null) {
        var temprep = sub.parentNode.parentNode.getAttribute("isRepeatable");
        var tempfeature = sub.parentNode.parentNode.getAttribute("code");
        for (var i = 0; i < selOs.length; i++) {
            if (selOs[i][0] == tempfeature && temprep == "false") {
                var old = document.getElementById(selOs[i][0] + ";" + selOs[i][1]);
                selOs.splice(i, 1);
                setStatus(old, "0");
                break;
            }
        }
    }
    var pFeature = null;
    for (var i = 0; i < selOs.length; i++) {
        if (selOs[i][0] == feature && !repeatable) {
            var old = document.getElementById(selOs[i][0] + ";" + selOs[i][1]);
            if (selOs[i][1].indexOf(".O") == selOs[i][1].length - 2) {
                var tempSubF = selOs[i][1].substring(0, selOs[i][1].length - 2);
                for (var j = 0; j < selOs.length; j++) {
                    if (selOs[j][0] == tempSubF && !repeatable) {
                        old = document.getElementById(selOs[j][0] + ";" + selOs[j][1]);
                        selOs.splice(j, 1);
                        break;
                    }
                }
            }
            selOs.splice(i, 1);
            setStatus(old, "0");
            break;
        }
        var common = findCommonParent(feature, selOs[i][0]);
        if (common != "") {
            var cRep = pafDoc.selectSingleNode('//Feature/FeatureSubset[@code="' + common + '"]').getAttribute("isRepeatable") == "true" ? true : false;
            if (!cRep) {
                var old = document.getElementById(selOs[i][0] + ";" + selOs[i][1]);
                selOs.splice(i, 1);
                setStatus(old, "0");
                break;
            }
        }
    }
    if (sub != null) {
        pFeature = sub.parentNode.parentNode.getAttribute("code");
    }
    selOs.push([feature, option, pFeature, auto]);
    setStatus(document.getElementById(feature + ";" + option), "2");
    var pRepeatable = false;
    var pOption = null;
    var key = feature + ";" + option;
    // var node = document.getElementById(key);
    //var subF = sub;
    while (sub != null) {
        pFeature = sub.parentNode.parentNode.getAttribute("code");
        pOption = sub.parentNode.getAttribute("code");
        pRepeatable = pafDoc.selectSingleNode('//Feature/FeatureSubset[@code="' + sub.parentNode.parentNode.getAttribute("code") + '"]').getAttribute("isRepeatable") == "true" ? true : false;

        for (var i = 0; i < selOs.length; i++) {
            if ((pFeature != null && selOs[i][2] == pFeature && !pRepeatable) && (feature != selOs[i][0])) {
                var old = document.getElementById(selOs[i][0] + ";" + selOs[i][1]);
                selOs.splice(i, 1);
                setStatus(old, "0");
                break;
            }
        }
        sub = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + sub.parentNode.parentNode.getAttribute("code") + '"]');
        var p = "";
        if (sub != null) {
            p = sub.getAttribute("featureCode");
        }
        loadExclusions(pFeature, pOption);
        selOs.push([pFeature, pOption, p, auto]);
    }
    for (var i = 0; i < exclusions.matches.length; i++) {
        var exclN = document.getElementById(exclusions.matches[i][0].key);
        if (exclN != null) {
            setStatus(exclN, "0");
        }
    }
    for (var i = 0; i < excShown.length; i++) {
        for (var j = 0; j < selOs.length; j++) {
            if (excShown[i][0] == selOs[j][0] && excShown[i][1] == selOs[j][1]) {
                var option = document.getElementById(selOs[j][0] + ";" + selOs[j][1]);
                if (option != null) {
                    setStatus(option, "0");
                }
                selOs.splice(j, 1);
                j--;
            }
        }
    }
}

function selectFeature(node, selection) {
    if (document.getElementById("initialimg") != null)
        document.getElementById("initialimg").style.display = "none";
    if (selOsNode != null) {
        var selnode = document.getElementById(selOsNode);
        if (selnode != null)
            selnode.style.display = "none";
    }
    if (node.loaded != "loaded") {
        loadOptions(node.feature);
        node.loaded = "loaded";
    }
    var options = document.getElementById(node.feature + ";options");
    if (options != null) {
        options.style.display = "inline-block";
        selOsNode = node.feature + ";options";
    }
    document.getElementById("topFrame").innerHTML = node.innerHTML;
    processExclusions(true);

    for (var fcount = 0; fcount < allFeature.length; fcount++) {
        if (document.getElementById(allFeature[fcount][0]) != null) {
            document.getElementById(allFeature[fcount][0]).style.backgroundColor = "";
            //document.getElementById(allFeature[fcount][0]).style.color="black"; 		
        }
    }
    if (document.getElementById(node.feature) != null) {
        document.getElementById(node.feature).style.backgroundColor = selF;
    }
    selFetureDisplay(node, selection);
    setOptionImgSize(node);
}

function setOptionImgSize(node) {
    var options = pafDoc.selectNodes('//Feature/FeatureSubset[@code="' + node.feature + '"]/OptionRef');
    var hsize = 0;
    var Wsize = 0;
    var isimg = false;
    for (var j = 0; j < options.length; j++) {
        var id = node.feature + ";optImg" + j;
        if (document.getElementById(id) != null) {
            var x = parseInt(document.getElementById(id).clientHeight);
            var y = parseInt(document.getElementById(id).clientWidth);
            isimg = true;
            if (x > hsize) {
                hsize = x;
            }
            if (y > Wsize) {
                Wsize = y;
            }
        }
    }
    if (hsize == 0 && isimg) {
        hsize = 150;
    }
    if (Wsize == 0 && isimg) {
        Wsize = 150;
    }

    for (var k = 0; k < options.length; k++) {
        var imgid = node.feature + ";optImg" + k;
        if (document.getElementById(imgid) != null) {
            if (node.feature == "DUMMY_END" || options[k].getAttribute("code") == ".") {
                var h = parseInt(document.getElementById("centerFrame").style.height);
                var w = parseInt(document.getElementById("centerFrame").style.width);
                h = h - 100;
                w = w - 100;
                document.getElementById(imgid).style.height = h;
                document.getElementById(imgid).style.width = w;
            }
        }
        var opt = node.feature + ";" + options[k].getAttribute("code");
        if (document.getElementById(opt) != null) {
            var tSize = Number(hsize) + 40;
            var twsize = Number(Wsize) + 50;
            if (node.feature == "DUMMY_END" || options[k].getAttribute("code") == ".") {
                var h = parseInt(document.getElementById("centerFrame").style.height);
                var w = parseInt(document.getElementById("centerFrame").style.width);
                h = h - 50;
                w = w - 50;
                document.getElementById(opt).style.height = h;
                document.getElementById(opt).style.width = w;
            } else {
                document.getElementById(opt).style.height = tSize;
                document.getElementById(opt).style.width = twsize;
            }
        }
    }
}


function selFetureDisplay(node, selection) {
    var option = "";
    var Nfea = "";
    if (selection == "0") {
        clearPane();
    }
    for (var i = 0; i < selOs.length; i++) {
        if (selOs[i][0] == node.feature) {
            option = selOs[i][1];
            Nfea = node.feature;
            if (option.indexOf(".O") != -1) {
                Nfea = option.substring(0, (option.length - 2));
                for (var j = 0; j < selOs.length; j++) {
                    if (selOs[j][0] == Nfea) {
                        option = selOs[j][1];
                        break;
                    }
                }
            }
            break;
        }
    }
    var islargImg = false;
    for (var si = 0; si < singleOpt.length; si++) {
        if (singleOpt[si] == node.feature) {
            HideOrExpand("Expand");
            islargImg = true;
            if (option != "") {
                showLargeDisplay(Nfea, option);
            }
        }
    }
    if (!islargImg) {
        HideOrExpand("Hide");
    }
}

function clearPane() {
    optName.innerHTML = "";
    largeImg.src = "";
    optDesc.innerHTML = "";
}

function selectSubF(node) {
    if (document.getElementById("initialimg") != null)
        document.getElementById("initialimg").style.display = "none";
    // var subfname = node.childNodes[0].innerHTML;
    if (selOsNode != null) {
        var selnode = document.getElementById(selOsNode);
        if (selnode != null)
            selnode.style.display = "none";
    }
    var subfeature = pafDoc.selectSingleNode('//Feature/FeatureSubset[@code="' + node.feature + '"]/OptionRef[@code="' + node.option + '"]/FeatureSubsetRef');
    if (node.loaded != "loaded") {
        loadOptions(subfeature.getAttribute("featureCode"));
        document.getElementById(node.id).loaded = "loaded";
    }
    var options = document.getElementById(subfeature.getAttribute("featureCode") + ";options");
    if (options != null) {
        options.style.display = "inline-block";
        selOsNode = subfeature.getAttribute("featureCode") + ";options";
    }

    var node = document.getElementById(subfeature.getAttribute("featureCode") + ";options");
    node.feature = subfeature.getAttribute("featureCode");
    setOptionImgSize(node);

    var subName = pafDoc.selectSingleNode('//Feature[@code="' + subfeature.getAttribute("featureCode") + '"]/DisplayName').text;
    while (subfeature != null) {
        subName = pafDoc.selectSingleNode('//Feature[@code="' + subfeature.parentNode.parentNode.getAttribute("code") + '"]/DisplayName').text + ' / ' + subName;
        subfeature = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + subfeature.parentNode.parentNode.getAttribute("code") + '"]');
    }
    document.getElementById("topFrame").innerHTML = subName;
    processExclusions(true);
}

function selectOption(node) {
    // var fNode = document.getElementById(node.feature);
    pushSelection(node.feature, node.option, false);
    purgeSelOs();
    clearFeatExclusions();
    processExclusions(true);
    refreshSelectedOptions();
    clearPane();
    showLargeDisplay(node.feature, node.option);
    isPremManFeature(node);
}

function isPremManFeature(node) {
    if (node == null) return;
    var isfound = false
    for (var j = 0; j < PmMandFeature.length; j++) {
        if (node.feature == PmMandFeature[j][0]) {
            if (PmMandFeature[j][1] == false) {
                preFeCount--;
                isfound = true;
                PmMandFeature[j][1] = true;
                break;
            }
        }
    }
    var tempfeature = node.feature;
    if (!isfound) {
        var preFeature = tempfeature;
        var parentFe = tempfeature;
        while (parentFe != null) {
            var cnode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + parentFe + '.O"]');
            if (cnode != null) {
                parentFe = cnode.parentNode.getAttribute("code");
                preFeature = parentFe;
            } else {
                parentFe = null;
            }
        }
        for (var j = 0; j < PmMandFeature.length; j++) {
            if (preFeature == PmMandFeature[j][0]) {
                if (PmMandFeature[j][1] == false) {
                    preFeCount--;
                    isfound = true;
                    PmMandFeature[j][1] = true;
                    break;
                }
            }
        }
    }

    if (preFeCount == 0) {
        for (var k = 0; k < stFeature.length; k++) {
            document.getElementById(stFeature[k]).disabled = false;
        }
    }

    var currCount = document.getElementById(node.feature);
    if (currCount == null) {
        var parentFe = node.feature;
        var preFeature = node.feature;
        while (parentFe != null) {
            var cnode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + parentFe + '.O"]');
            if (cnode != null) {
                parentFe = cnode.parentNode.getAttribute("code");
                preFeature = parentFe;
            } else {
                parentFe = null;
            }
        }
        currCount = document.getElementById(preFeature).order;
    } else {
        currCount = currCount.order;
    }

    var isFound = selOrder(currCount, preFeCount, node);
    if (isFound == false) selOrder(0, preFeCount, node);
}

function selOrder(orderId, preFeCount, node) {
    var isFound = false;
    for (var i = orderId; i < fOrder.length; i++) {
        if (preFeCount == 0) {
            var count = Number(i);
            var feature = fOrder[count][0];
            this.feature = feature;
            var isRep = false;
            for (var ir = 0; ir < isRepFeat.length; ir++) {
                if (node.feature == isRepFeat[ir]) {
                    isRep = true;
                    break;
                }
            }

            if (isRep == false) {
                selectFeature(document.getElementById(feature), "0");
            }
            var cnode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + node.feature + '.O"]');

            if (cnode != null) {

                var parentFe = node.feature;
                var preFeature = node.feature;
                while (parentFe != null) {
                    var cnode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + parentFe + '.O"]');
                    if (cnode != null) {
                        parentFe = cnode.parentNode.getAttribute("code");
                        preFeature = parentFe;
                    } else {
                        parentFe = null;
                    }
                }
                var isRep = false;
                for (var ir = 0; ir < isRepFeat.length; ir++) {
                    if (preFeature == isRepFeat[ir]) {
                        isRep = true;
                        break;
                    }
                }

                if (isRep == true) {
                    selectFeature(document.getElementById(preFeature), "0");
                }
            }
            isFound = true;
            break;
        } else {
            var count = Number(i);
            if (fOrder[count][1] == "mFeature") {
                var feature = fOrder[count][0];
                this.feature = feature;
                var isRep = false;
                for (var ir = 0; ir < isRepFeat.length; ir++) {
                    if (node.feature == isRepFeat[ir]) {
                        isRep = true;
                        break;
                    }
                }
                if (isRep == false) {
                    selectFeature(document.getElementById(feature), "0");
                }
                var cnode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + node.feature + '.O"]');

                if (cnode != null) {
                    var parentFe = node.feature;
                    var preFeature = node.feature;
                    while (parentFe != null) {
                        var cnode = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + parentFe + '.O"]');
                        if (cnode != null) {
                            parentFe = cnode.parentNode.getAttribute("code");
                            preFeature = parentFe;
                        } else {
                            parentFe = null;
                        }
                    }

                    var isRep = false;
                    for (var ir = 0; ir < isRepFeat.length; ir++) {
                        if (preFeature == isRepFeat[ir]) {
                            isRep = true;
                            break;
                        }
                    }
                    if (isRep == true) {
                        selectFeature(document.getElementById(preFeature), "0");
                    }
                }

                isFound = true;
                break;
            }
        }
    }
    return isFound;
}

function HideOrExpand(value) {
    if (value == "Expand") {
        var w = document.getElementById("centerFrame").parentNode.offsetWidth;
        var cw = (w / 100) * spSize;
        document.getElementById("centerFrame").style.width = cw + "px";
        var cw2 = w - cw;
        document.getElementById("centerFrame2").style.width = cw2 + "px";
    }
    if (value == "Hide") {
        var width = document.getElementById("centerFrame").parentNode.offsetWidth - 0 - 0;
        if (width < 5) width = 5;
        document.getElementById("centerFrame").style.width = width + "px";
        document.getElementById("centerFrame2").style.display = "none";
    }
}

function showLargeDisplay(feature, option) {
    var isrcN = pafDoc.selectSingleNode('//Feature [@code="' + feature + '"]/Option[@code="' + option + '"]/Multimedia[@type="LargeImage"]');
    var OptionLink = pafDoc.selectSingleNode('//Feature [@code="' + feature + '"]/Option[@code="' + option + '"]/Multimedia[@type="Info"]');
    var OptCode = pafDoc.selectNodes('//Feature [@code="' + feature + '"]/Option[@code="' + option + '"]');

    var line1 = "";
    var line2 = "";
    var line3 = "";
    var line4 = "";
    var line5 = "";
    var line6 = "";
    var line7 = "";
    if (isrcN != null) {
        isrc = "..\\" + isrcN.text;
        centerFrame2.style.display = "inline";
        optName.innerHTML = OptCode[0].selectSingleNode("DisplayName").text;
        largeImg.src = isrc;
        var customData = OptCode[0].selectSingleNode("CustomData");
        var optCuData = getXML(customData.text);
        var GSVline = optCuData.selectNodes("//GSV");
        if (GSVline != null) {
            for (var GSVc = 0; GSVc < GSVline.length; GSVc++) {
                if (GSVline[GSVc].getAttribute("addInfo1") !== null && GSVline[GSVc].getAttribute("addInfo1") !== "") {
                    line1 = GSVline[GSVc].getAttribute("addInfo1");
                    line1 = "<P>" + line1 + "</P>";
                }
                if (GSVline[GSVc].getAttribute("addInfo2") !== null && GSVline[GSVc].getAttribute("addInfo2") !== "") {
                    line2 = GSVline[GSVc].getAttribute("addInfo2");
                    line2 = "<P>" + line2 + "</P>";
                }
                if (GSVline[GSVc].getAttribute("addInfo3") !== null && GSVline[GSVc].getAttribute("addInfo3") !== "") {
                    line3 = GSVline[GSVc].getAttribute("addInfo3");
                    line3 = "<P>" + line3 + "</P>";
                }
                if (GSVline[GSVc].getAttribute("addInfo4") !== null && GSVline[GSVc].getAttribute("addInfo4") !== "") {
                    line4 = GSVline[GSVc].getAttribute("addInfo4");
                    line4 = "<P>" + line4 + "</P>";
                }
                if (GSVline[GSVc].getAttribute("addInfo5") !== null && GSVline[GSVc].getAttribute("addInfo5") !== "") {
                    line5 = GSVline[GSVc].getAttribute("addInfo5");
                    line5 = "<P>" + line5 + "</P>";
                }
                if (GSVline[GSVc].getAttribute("addInfo6") !== null && GSVline[GSVc].getAttribute("addInfo6") !== "") {
                    line6 = GSVline[GSVc].getAttribute("addInfo6");
                    line6 = "<P>" + line6 + "</P>";
                }
                if (GSVline[GSVc].getAttribute("addInfo7") !== null && GSVline[GSVc].getAttribute("addInfo7") !== "") {
                    line7 = GSVline[GSVc].getAttribute("addInfo7");
                    line7 = "<P>" + line7 + "</P>";
                }
            }
            var line8 = "";
            if (OptionLink != null) {
                line8 = "<a style=color:blue;text-decoration:underline;cursor:pointer;   id=demo onclick=openlink(this.value) value=" + OptionLink.text + ">More Information</a>";
            }


            var line = line1 + line2 + line3 + line4 + line5 + line6 + line7 + line8;
            optDesc.innerHTML = line;
        }
        HideOrExpand("Expand");
    } else {
        clearPane();
    }
}

function openlink(linktext) {
    window.open(linktext);
}

function processExclusions(mode) {
    for (var i = 0; i < exclusions.matches.length; i++) {
        var exclN = document.getElementById(exclusions.matches[i][0].key);
        if (exclN != null) {
            setStatus(exclN, "0");
        }
    }
    exclusions = new Matches();
    inclusion = new Matches();
    var selOsKeys = [];
    for (var i = 0; i < selOs.length; i++) {
        selOsKeys.push(new Key(selOs[i][0] + ";" + selOs[i][1]));
    }
    getInclMatches(selOsKeys, inclusion);

    for (var i = 0; i < selOs.length; i++) {
        //inclusion
        var selOsk = [];
        var tempInclusion = new Matches();
        selOsk.push(new Key(selOs[i][0] + ";" + selOs[i][1]));
        getInclMatches(selOsk, tempInclusion);
        if (tempInclusion.matches.length == 0) {
            continue;
        }

        if (inclusion.matches.length == 0) { // if none feature selected			
            for (var tempInclCount = 0; tempInclCount < tempInclusion.matches.length; tempInclCount++) { // featurewise restrctions
                var tempKey = new Key;
                var arrayKey = [];
                tempKey.key = tempInclusion.matches[tempInclCount][0].key;
                arrayKey.push(tempKey, 1);
                inclusion.matches.push(arrayKey)
            }
        }
        else {
            var length = inclusion.matches.length;
            var removeKeys = [];
            var NewKeys = [];
            for (var j = 0; j < length; j++) {
                var isfound = false;
                var tFeature = inclusion.matches[j][0].key.split(";")[0];
                var isfeatureFound = false;
                for (var tempInclCount = 0; tempInclCount < tempInclusion.matches.length; tempInclCount++) {
                    var t2Feature = tempInclusion.matches[tempInclCount][0].key.split(";")[0];
                    if (inclusion.matches[j][0].key == tempInclusion.matches[tempInclCount][0].key) // check common feature and option and keep those visible
                    {
                        isfound = true;
                        break;
                    }
                    if (tFeature == t2Feature) // check feature restrctions are exist in inclusion otherwise add all inclusions
                    {
                        isfeatureFound = true;
                    }
                }
                if (!isfound) {
                    removeKeys.push(inclusion.matches[j][0].key); //  remove uncommon option under same feature								
                }
                if (!isfeatureFound) {
                    NewKeys.push(inclusion.matches[j][0].key);
                }

            }
            for (var rk = 0; rk < removeKeys.length; rk++) // remove uncommon option under same feature	
            {
                for (var j = 0; j < length; j++) {
                    if (removeKeys[rk] == inclusion.matches[j][0].key) {
                        inclusion.matches.splice(j, 1);
                        break;
                    }
                }
            }
            for (var nk = 0; nk < NewKeys.length; nk++) // add common feature and option
            {
                var tempKey = new Key;
                var arrayKey = [];
                tempKey.key = NewKeys[nk];
                arrayKey.push(tempKey, 1);
                inclusion.matches.push(arrayKey)
            }
        }
    }
    getExclMatches(selOsKeys, exclusions);
    var InclusionFeature = [];
    var ArryInclusion = [];
    for (var i = 0; i < inclusion.matches.length; i++) {

        var tempFeature = inclusion.matches[i][0].key.split(";")[0];
        if (!contains(InclusionFeature, tempFeature)) {
            InclusionFeature.push(tempFeature);
        }
        ArryInclusion.push(inclusion.matches[i][0].key);
    }

    if (ArryInclusion.length > 0) {
        for (var k = 0; k < tempfeatureOption.length; k++) {
            var tempFeature = tempfeatureOption[k][0];
            if (!contains(InclusionFeature, tempFeature)) continue;
            var tempOptions = tempfeatureOption[k][1];
            for (var opcount = 0; opcount < tempOptions.length; opcount++) {
                var optioncode = tempOptions[opcount];
                var value = tempFeature + ";" + optioncode;
                var isFeatFound = false;
                for (var inCount = 0; inCount < ArryInclusion.length; inCount++) {
                    var featopt = ArryInclusion[inCount];
                    if (value == featopt) // check feature option relation exist in inclusion array or not
                    {
                        isFeatFound = true;
                        break;

                    }
                }
                if (!isFeatFound) {
                    var isexclusionExist = false;
                    for (var execount = 0; execount < exclusions.matches.length; execount++) {
                        if (exclusions.matches[execount][0].key == value) {
                            isexclusionExist = true;
                            break;
                        }
                    }
                    if (isexclusionExist) {
                        continue;
                    }
                    var tempKey = new Key;
                    var arrayKey = [];
                    tempKey.key = value;


                    arrayKey.push(tempKey, 1);
                    exclusions.matches.push(arrayKey);
                }
            }
        }
    }

    var subExclusions = [];
    for (var i = 0; i < exclusions.matches.length; i++) {
        var exclN = document.getElementById(exclusions.matches[i][0].key);
        excludeSubFeatures(exclN, subExclusions);
    }
    for (var i = 0; i < subExclusions.length; i++) {
        exclusions.insert(subExclusions[i]);
    }

    hideExclusions();
    countExclusions(mode);
}

function excludeSubFeatures(exclN, subExclusions) {
    if (exclN != null) {
        setStatus(exclN, "3");
        var sCode = exclN.option.substr(0, exclN.option.length - 2);
        var options = document.getElementById(sCode + ";options");
        if (options != null) {
            for (var j = 0; j < options.childNodes.length; j++) {
                setStatus(options.childNodes[j], "3");
                subExclusions.push(new Key(options.childNodes[j].feature + ";" + options.childNodes[j].option));
                excludeSubFeatures(options.childNodes[j], subExclusions);
            }
        }
    }
}

function pushExcShown(key) {
    for (var i = 0; i < excShown.length; i++) {
        if (excShown[i][0] == key[0] && excShown[i][1] == key[1])
            return;
    }
    excShown.push(key);
}

function clearFeatExclusions() {
    for (var i = 0; i < excShown.length; i++) {
        var feature = document.getElementById("f;" + excShown[i][0] + ";" + excShown[i][1]);
        if (feature != null) {
            feature.className = "selectedOption";
        }
        var option = document.getElementById(excShown[i][0] + ";" + excShown[i][1]);
        if (option != null) {
            if (option.status == "3") {
                setStatus(option, "0");
            }
        }
    }
    excShown = [];
}

function showExclusions(node) {
    if (node.status != "3")
        return;
    var selOsKeys = [];
    for (var i = 0; i < selOs.length; i++) {
        selOsKeys.push(new Key(selOs[i][0] + ";" + selOs[i][1]));
    }
    selOsKeys.push(new Key(node.feature + ";" + node.option));
    var feat = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + node.feature + '"]');
    while (feat != null) {
        var pF = feat.parentNode.parentNode.getAttribute("code");
        var pO = feat.parentNode.getAttribute("code");
        var found = false;
        for (var i = 0; i < selOsKeys.length; i++) {
            if (selOsKeys[i].key == pF + ";" + pO) {
                found = true;
                break;
            }
        }
        if (!found) {
            selOsKeys.push(new Key(pF + ";" + pO));
        }
        feat = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + feat.parentNode.parentNode.getAttribute("code") + '"]');
    }
    var excl = new Matches();
    getExclMatches(selOsKeys, excl);
    // if an option was automatically set, we need to also exclude options that were responsible for the automatically set options

    for (var i = 0; i < selOs.length; i++) {
        if (!selOs[i][3]) continue;
        for (var j = 0; j < excl.matches.length && !found; j++) {
            if (excl.matches[j][0].key == selOs[i][0] + ";" + selOs[i][1]) {
                var triggers = findAutoTriggers(selOs[i][0], selOs[i][1]);
                //if (triggers.length > 0) alert(triggers[0][0]+";"+triggers[0][1]);
                for (var k = 0; k < triggers.length; k++) {
                    excl.insert(new Key(triggers[0][0] + ";" + triggers[0][1], null), 0)
                }
            }
        }
    }

    for (var i = 0; i < selOs.length; i++) {
        var codes = [
            [selOs[i][0], selOs[i][1]]
        ];
        var feat = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + selOs[i][0] + '.O"]');
        while (feat != null) {
            var fCode = feat.parentNode.getAttribute("code");
            var oCode = feat.getAttribute("code");
            codes.push([fCode, oCode]);
            feat = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef[@code="' + fCode + '.O"]');
        }
        var found = false;
        for (var j = 0; j < excl.matches.length && !found; j++) {
            if (node.feature + ";" + node.option == excl.matches[j][0].key)
                continue;
            var featopt = excl.matches[j][0].key.split(";");
            for (var k = 0; k < codes.length && !found; k++) {
                if (featopt[0] == codes[k][0] && featopt[1] == codes[k][1]) {
                    var fNode = document.getElementById("f;" + selOs[i][0] + ";" + selOs[i][1]);
                    if (fNode != null) {
                        pushExcShown([selOs[i][0], selOs[i][1]]);
                        fNode.className = "featureExcluded";
                    }
                    found = true;
                }
            }
        }
    }
}

function purgeSelOs() {
    for (var i = 0; i < selOs.length; i++) {
        // remove auto opts
        if (selOs[i][3]) {
            selOs.splice(i, 1);
            i--;
            continue;
        }

        var sub = pafDoc.selectSingleNode('//Feature/FeatureSubset/OptionRef/FeatureSubsetRef[@featureCode="' + selOs[i][1].substr(0, selOs[i][1].length - 2) + '"]');
        if (sub != null) {
            var found = false;
            for (var j = 0; j < selOs.length; j++) {
                if (selOs[j][0] + ".O" == (selOs[i][1])) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                var node = document.getElementById(selOs[i][0] + ";" + selOs[i][1]);
                if (node != null) {
                    setStatus(node, "0");
                }
                selOs.splice(i, 1);
                i--;
            }
        }
    }
}

function setHidden() {
    var status = document.getElementById("hideExcl").hide;
    if (status == "0") {
        document.getElementById("hideExcl").hide = "1";
        document.getElementById("hideExcl").innerHTML = document.getElementById("hideExcl").showT;
    } else {
        document.getElementById("hideExcl").hide = "0";
        document.getElementById("hideExcl").innerHTML = document.getElementById("hideExcl").hideT;
    }
    hideExclusions();
}

function hideExclusions() {
    var status = document.getElementById("hideExcl").hide;
    if (status == "1") {
        for (var i = 0; i < oDiv.childNodes.length; i++) {
            for (var j = 0; j < oDiv.childNodes[i].childNodes.length; j++) {
                if (oDiv.childNodes[i].childNodes[j].status == "3") {
                    oDiv.childNodes[i].childNodes[j].style.display = "none";
                } else {
                    oDiv.childNodes[i].childNodes[j].style.display = "inline-block";
                }
            }
        }
    } else {
        for (var i = 0; i < oDiv.childNodes.length; i++) {
            for (var j = 0; j < oDiv.childNodes[i].childNodes.length; j++) {
                oDiv.childNodes[i].childNodes[j].style.display = "inline-block";
            }
        }
    }
}

function getXML(xmlStr) {
    var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async = "false";
    xmlDoc.loadXML(xmlStr);
    return xmlDoc;
}

function validateOverride() {
    if (excShown.length > 0) {
        var msg = document.getElementById("delMsg").txt + "\n";
        for (var i = 0; i < excShown.length; i++) {
            msg += excShown[i][1] + "\n";
        }
        return confirm(msg);
    }
    return true;
}

function clearOpts() {
    var msg = document.getElementById("clrMsg").txt;
    if (!confirm(msg))
        return;
    preFeCount = PmMandFeature.length;
    for (var k = 0; k < stFeature.length; k++) {
        document.getElementById(stFeature[k]).disabled = true;
    }
    for (var i = 0; i < selOs.length; i++) {
        var old = document.getElementById(selOs[i][0] + ";" + selOs[i][1]);
        selOs.splice(i, 1);
        if (old != null) {
            setStatus(old, "0");
        }
        i--;
    }
    for (var i = 0; i < exclusions.matches.length; i++) {
        var old = document.getElementById(exclusions.matches[i][0].key);
        exclusions.matches.splice(i, 1);
        if (old != null) {
            setStatus(old, "0");
        }
        i--;
    }
    for (var j = 0; j < PmMandFeature.length; j++) {
        PmMandFeature[j][1] = false;
    }
    if (PmMandFeature.length == 0) {
        for (var k = 0; k < stFeature.length; k++) {
            document.getElementById(stFeature[k]).disabled = false;
        }
    }
    exclusions = new Matches();
    clearFeatExclusions();
    processExclusions(true);
    refreshSelectedOptions();
}

function toggleDisplay() {
    var selnode = document.getElementById(selOsNode);
    if (selnode != null) {
        switchDisplayMode(selnode);
    }
}

function valManOpt() {
    var mFeature = optCount.slice();
    for (var t = 0; t < assoFeature.length; t++) {
        for (var mos = 0; mos < mFeature.length; mos++) {
            if (assoFeature[t][0] == mFeature[mos][0]) {
                mFeature.splice(mos, 1);
                break;
            }
        }
    }
    for (var hf = 0; hf < hiddenFeature.length; hf++) {
        for (var mf = 0; mf < mFeature.length; mf++) {
            if (hiddenFeature[hf] == mFeature[mf][0]) {
                mFeature.splice(mf, 1);
                break;
            }
        }
    }
    for (var i = 0; i < selOs.length; i++) {
        for (var mo = 0; mo < mFeature.length; mo++) {
            if (selOs[i][0] == mFeature[mo][0]) {
                mFeature.splice(mo, 1);
                break;
            }
        }
        if (i == (selOs.length - 1)) {
            if (mFeature.length != 0) {
                var msg = "Below mandatory feature needs to have an option selected: \n";
                for (var ms = 0; ms < mFeature.length; ms++) {
                    msg += mFeature[ms][3] + " \n";
                }
                alert(msg);
                return false;
            }
        }
    }
    return true;
}

function submitStyles() {
    if (!valManOpt()) return;
    var submitstr = "DELETE_ALL";
    var opt = "";
    for (var i = 0; i < selOs.length; i++) {
        if (selOs[i][1].indexOf(".O") == selOs[i][1].length - 2) {
            opt = selOs[i][1].substring(0, (selOs[i][1].length - 2));
            var isFeature = false;
            for (var fo = 0; fo < allFeature.length; fo++) {
                if (allFeature[fo][0] == opt) {
                    isFeature = true;
                    break;
                }
            }
            if (isFeature) continue;
        }

        var node = document.getElementById(selOs[i][0] + ";" + selOs[i][1]);
        var reckey = "";

        if (node != null) {
            reckey = node.reckey;
        } else {
            var custom = pafDoc.selectSingleNode('//Feature[@code="' + selOs[i][0] + '"]/Option[@code="' + selOs[i][1] + '"]/CustomData');
            if (custom != null) {
                var customData = getXML(custom.text);
                var reckeynode = customData.selectSingleNode("//RECKEY");
                if (reckeynode)
                    reckey = reckeynode.getAttribute("code");
            }
        }
        if (reckey != "") {
            submitstr += "&RECKEY:" + reckey;
        }
    }
    var selprod = [];
    for (var rpp = 0; rpp < relProducts.length; rpp++) {
        if (relProducts[rpp].length <= 3) {
            var relFeature = relProducts[rpp][1];
            var relOption = relProducts[rpp][2];
            for (var selFe = 0; selFe < selOs.length; selFe++) {
                if (selOs[selFe][0] == relFeature && selOs[selFe][1] == relOption) {
                    var tempex = isElementExist(selprod, relProducts[rpp][0])
                    if (!tempex) {
                        selprod.push(relProducts[rpp][0]);
                    }
                    break;
                }
            }
        }
        if (relProducts[rpp].length > 3 && relProducts[rpp].length <= 7) {
            var relFeature = relProducts[rpp][1];
            var relOption = relProducts[rpp][2];
            var relFeature1 = relProducts[rpp][3];
            var relOption1 = relProducts[rpp][4];
            var relFeature2 = "";
            var relOption2 = "";
            if (relProducts[rpp].length > 5) {
                relFeature2 = relProducts[rpp][5];
                relOption2 = relProducts[rpp][6];
            }
            var isFirst = false;
            var isSecond = false;
            var isThird = false;
            for (var selFe = 0; selFe < selOs.length; selFe++) {
                if (selOs[selFe][0] == relFeature && selOs[selFe][1] == relOption) {
                    isFirst = true;
                }
                if (selOs[selFe][0] == relFeature1 && selOs[selFe][1] == relOption1) {
                    isSecond = true;
                }
                if (selOs[selFe][0] == relFeature2 && selOs[selFe][1] == relOption2) {
                    isThird = true;
                }
                if (isFirst && isSecond) {
                    if (relProducts[rpp].length <= 5) {
                        var tempex = isElementExist(selprod, relProducts[rpp][0])
                        if (!tempex) {
                            selprod.push(relProducts[rpp][0]);
                        }
                        break;
                    } else {
                        if (isThird) {
                            var tempex = isElementExist(selprod, relProducts[rpp][0])
                            if (!tempex) {
                                selprod.push(relProducts[rpp][0]);
                            }
                            break;
                        }
                    }
                }
            }
        }
    }
    if (selprod.length != 0) {
        for (ir = 0; ir < selprod.length; ir++) {
            var key = getReckKey(selprod[ir]);
            submitstr += key;
        }
    }
    loadPricesMatches();
    var prices = new Matches();
    var selOsKeys = [];
    for (var i = 0; i < selOs.length; i++) {
        selOsKeys.push(new Key(selOs[i][0] + ";" + selOs[i][1]));
    }
    priceMap.getKeys(selOsKeys, prices, 0);

    var priceLvls = [];
    for (var i = 0; i < prices.matches.length; i++) {
        if (!arrayContains(prices.matches[i][0], selOsKeys))
            continue;
        arrayPush([prices.matches[i][0].data, prices.matches[i][1]], priceLvls);
    }
    if (priceLvls.length > 1) {
        var lvl = -1;
        var price = -1;
        var mult = false;
        for (var i = 0; i < priceLvls.length; i++) {
            if (priceLvls[i][1] > lvl) {
                lvl = priceLvls[i][1];
                price = priceLvls[i][0];
                mult = false;
            } else if (priceLvls[i][1] == lvl) {
                mult = true;
            }
        }
        if (mult) {
            alert(document.getElementById("pLvlMsg").txt);
        } else {
            submitstr += "&PL=" + price;
        }
    } else if (priceLvls.length == 1) {
        submitstr += "&PL=" + priceLvls[0][0];
    }
    if (submitstr.length == 10)
        submitstr += "&USERKODE:";

    parent.returnValue = submitstr;
    parent.close();
}

function isElementExist(array, value) {
    for (var k = 0; k < array.length; k++) {
        if (array[k] == value) {
            return true;
        }
    }
    return false;
}

function getReckKey(selprod) {
    var RelPcust = pafDoc.selectSingleNode('//Product[@code="' + selprod + '"]/CustomData');
    var key = "";
    if (RelPcust.length != 0) {
        var recustomData = getXML(RelPcust.text);
        var reckeynode1 = recustomData.selectSingleNode("//RECKEY");
        if (reckeynode1) {
            var reckey1 = reckeynode1.getAttribute("code");
            if (reckey1 != "") {
                key = "&RECKEY:" + reckey1;
            }
        }
    }
    return key;
}

function arrayPush(element, array) {
    for (var i = 0; i < array.length; i++) {
        if (array[i][0] == element[0] && array[i][1] == element[1])
            return false;
    }
    array.push(element);
    return true;
}

function arrayContains(element, array) {
    for (var i = 0; i < array.length; i++) {
        if (array[i].key == element.key)
            return true;
    }
    return false;
}