if (!window.ActiveXObject) {
    Element.prototype.selectNodes = function(sXPath) {
        var oEvaluator = new XPathEvaluator();
        var oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
        var aNodes = new Array();

        if (oResult != null) {
            var oElement = oResult.iterateNext();
            while(oElement) {
            aNodes.push(oElement);
            oElement = oResult.iterateNext();
            }
        }
        return aNodes;
    }

    Element.prototype.selectSingleNode = function(sXPath) {
        var oEvaluator = new XPathEvaluator();

          // FIRST_ORDERED_NODE_TYPE returns the first match to the xpath.
        var oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
        if (oResult != null) {
            return oResult.singleNodeValue;
        } else {
            return null;
        }              
    }
}

function loadXMLDoc(dname) {
    if (window.XMLHttpRequest)
      {
      xhttp=new XMLHttpRequest();
      }
    else
      {
      xhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
    xhttp.open("GET",dname,false);
    xhttp.send("");
    return xhttp.responseXML;
}

function displayResult(xml, xsl, strElementName) {
//            xml=loadXMLDoc(strXMLfileName);
//            xsl=loadXMLDoc(strXSLfileName);
    // code for IE
    if (window.ActiveXObject)
      {
      ex=xml.transformNode(xsl);
      document.getElementById(strElementName).innerHTML=ex;
      }
    // code for Mozilla, Firefox, Opera, etc.
    else if (document.implementation && document.implementation.createDocument)
      {
      xsltProcessor=new XSLTProcessor();
      xsltProcessor.importStylesheet(xsl);
      resultDocument = xsltProcessor.transformToFragment(xml,document);
      document.getElementById(strElementName).innerHTML='';

      document.getElementById(strElementName).appendChild(resultDocument);
      }
}

function testFindMutualEnemies(){
    var newID=0
    var nodeR=xmlLists.firstChild.ownerDocument.createElement("results");
    //loop through every army and every enemy
    var a=xmlLists.firstChild.selectNodes("/data/army")
    for (var i=0; i<a.length; i++){
        //e.g. 6
        var a2=a[i].selectNodes("enemies/enemy[@code != '" + a[i].getAttribute("code") + "']")
        for (var j=0; j<a2.length; j++){
            /*
            Possibilities are
            1) Start a new tuple
            2) Build on an existing. There must be a tuple where both are a me
            */
        }
    }
    
}
var NEWID = 0 
var TUPLEID=0
function findMutualEnemies(){
    var nodeR=xmlLists.firstChild.ownerDocument.createElement("tuples");
    //build triples
   
    var a=xmlLists.firstChild.selectNodes("/data/army")
    for (var i = 0; i < a.length; i++) //
    {
        a[i].setAttribute("id", i);
    }
    var a=xmlLists.firstChild.selectNodes("/data/army")
    for (var i = 0; i < a.length; i++) //
    {
        //e.g. 6
        var a2=a[i].selectNodes("enemies/enemy[@code > '" + a[i].getAttribute("code") + "']")
        for (var j = 0; j < a2.length; j++) {
            //build tuples - but only in one direction
            var nodeT=a[i].ownerDocument.createElement("tuple");
            nodeR.appendChild(nodeT);
            nodeT.setAttribute("members", 2);
            nodeT.setAttribute("id", TUPLEID);
            TUPLEID=TUPLEID + 1
            createTupleMember(nodeT, a[i].getAttribute("code"));
            createTupleMember(nodeT, a2[j].getAttribute("code"));
        }
    }
    for (var currMembers = 2; currMembers < 100;  i++) {
        //removeDuplicateTuples(nodeR);
        var a = nodeR.selectNodes("tuple[@members=" + currMembers + "]")
//        alert(currMembers + ':' + a.length);
        for (var i = 0; i < a.length; i++) {
            enlargeTuple(a[i]);
        }
        if (a.length == 0) {
            currMembers = 100;
        }
        currMembers = currMembers + 1
    }

    var a = nodeR.selectNodes("tuple[@incomplete or @members=2]")
    for (var i = 0; i < a.length; i++) {
        a[i].parentNode.removeChild(a[i]);
    }
    debugger
    var a = nodeR.selectNodes("tuple")
    for (var i = a.length - 1; i > -1; i--) {
        removeSubsets(a[i]);
    }    
    addNames(nodeR);
    debugger
} 
function addNames(nodeR){
    var a = nodeR.selectNodes("tuple/army")
    for (var i = 0; i < a.length; i++) {
        var nodeT=xmlLists.firstChild.selectSingleNode("army[@code='" + a[i].getAttribute("code") + "']")
        if(nodeT){
            a[i].setAttribute("name", nodeT.getAttribute("name"));
        }
    }
}

function enlargeTuple(nodeT){
    /*
    take the tuple, build an xpath to find armies to add to it
    if found create new tuples for each one.
    */
    var strPath;
    var strSpacer="";
    strPath="army[";
    var a = nodeT.selectNodes("army")
    for (var i = 0; i < a.length; i++) {
        strPath=strPath + strSpacer + "enemies/enemy/@code = '" + a[i].getAttribute("code") + "'"
        strSpacer = " and "
        if (i == a.length - 1) {
            strPath = strPath + " and @code > '" + a[i].getAttribute("code") + "'"
        }
    }
    strPath = strPath + "]";
    var a = xmlLists.firstChild.selectNodes(strPath)
    for (var i = 0; i < a.length; i++) {
        createNewTuple(nodeT, a[i].getAttribute("code"));
    }
}
function removeSubsets(nodeT){
    var strPath;
    var strSpacer="";
    strPath="tuple[";
    var a = nodeT.selectNodes("army")
    for (var i = 0; i < a.length; i++) {
        strPath=strPath + strSpacer + "army/@code = '" + a[i].getAttribute("code") + "'"
        strSpacer = " and "
        if (i == a.length - 1) {
            strPath = strPath + " and @members > '" + nodeT.getAttribute("members") + "'"
        }
    }
    strPath = strPath + "]";
    if(nodeT.parentNode.selectSingleNode(strPath)){
        nodeT.parentNode.removeChild(nodeT);
    }
}
function createNewTuple(nodeBase, newCode) {
    var nodeT = nodeBase.ownerDocument.createElement("tuple");
    nodeT = nodeBase.cloneNode(true);
    nodeBase.setAttribute("incomplete", 1);
    nodeBase.parentNode.appendChild(nodeT);
    nodeT.setAttribute("members", parseInt(nodeBase.getAttribute("members"))+1);
    nodeT.setAttribute("id", TUPLEID);
    nodeT.setAttribute("parent_id", nodeBase.getAttribute("id"));
    TUPLEID=TUPLEID + 1    
    nodeT.removeAttribute("incomplete");
    createTupleMember(nodeT, newCode);
}
function findComplimentaryTuples(){
    /*
    tries to find another pair of tuples that add a member. If so, copy it.
    ABC + BCD + ABD = ABCD
    ABCD + ABE + BCE + CDE = ABCDE or ABCD + ABDE + ABC =  
    needs to find at
    */
}

function removeDuplicateTuples(nodeR){
    /*
    remove duplicates
    */
    
    debugger
    var a=nodeR.selectNodes("tuple")
    for (var i=0; i<a.length; i++){
        var strPath="tuple[@id > " + a[i].getAttribute("id") + " and @members=" + a[i].selectNodes("army").length
        var a2=a[i].selectNodes("army")
        for (var i2=0; i2<a2.length; i2++){
            strPath=strPath + " and army/@code='" + a2[i2].getAttribute("code") + "'"
        }    
        strPath=strPath + "]"
        var nodeT=nodeR.selectSingleNode(strPath);
/*
        if(nodeT){
            nodeT.parentNode.removeChild(nodeT);
        }
*/
        
        var a3=nodeR.selectNodes(strPath)  
        for (var i3=0; i3<a3.length; i3++){
            if(a3[i3].selectNodes("army").length==a2.length){
                //only remove if same length - i.e. exact duplicate not part of larger tuple
                a3[i3].parentNode.removeChild(a3[i3]);
            }
        } 
    }    
}

function createTupleMember(nodeTuple, strCode){
    var nodeCheck=nodeTuple.selectSingleNode("army[@code='" + strCode + "']");
    if(!nodeCheck){
        var nodeT=nodeTuple.ownerDocument.createElement("army");
        nodeT.setAttribute("code", strCode);
        nodeTuple.appendChild(nodeT);  
    }
}
