/*global rg2:false */
(function () {
  function ResultParserIOFV3(xml) {
    this.results = [];
    this.valid = true;
    this.processIOFV3Results(xml);
    return {results: this.results, valid: this.valid};
  }

  ResultParserIOFV3.prototype = {

    Constructor : ResultParserIOFV3,

    getID : function (element, name) {
      var temp;
      if (element.length > 0) {
        temp = element[0].textContent;
        // remove new lines from empty <Id> tags
        temp.replace(/[\n\r]/g, '');
        return (temp.trim() + "__" + name);
      }
      // no id defined so just use count of runners
      return (this.results.length + "__" + name);
    },

    getClub : function (element) {
      if (element.length > 0) {
        return element[0].getElementsByTagName('Name')[0].textContent;
      }
      return "";
    },

    processIOFV3Results : function (xml) {
      var classlist, personlist, resultlist, i, j, result, course, temp;
      try {
        classlist = xml.getElementsByTagName('ClassResult');
        for (i = 0; i < classlist.length; i += 1) {
          temp = classlist[i].getElementsByTagName('Class');
          course = temp[0].getElementsByTagName('Name')[0].textContent;
          personlist = classlist[i].getElementsByTagName('PersonResult');
          for (j = 0; j < personlist.length; j += 1) {
            result = {};
            result.course = course;
            temp = personlist[j].getElementsByTagName('Given')[0].textContent + " " + personlist[j].getElementsByTagName('Family')[0].textContent;
            // remove new lines from empty <Given> and <Family> tags
            result.name = temp.replace(/[\n\r]/g, '').trim();
            result.dbid = this.getID(personlist[j].getElementsByTagName('Id'), result.name);
            result.club = this.getClub(personlist[j].getElementsByTagName('Organisation'));
            resultlist = personlist[j].getElementsByTagName('Result');
            this.extractIOFV3Results(resultlist, result);
            this.results.push(result);
          }
        }
      } catch (err) {
        this.valid = false;
        rg2.utils.showWarningDialog("XML parse error", "Error processing XML file. Error is : " + err.message);
        return;
      }
    },

    getStartFinishTimeAsSeconds : function (time) {
      if (time.length >= 19) {
        // format is yyyy-mm-ddThh:mm:ss and might have extra Z or +nn
        return rg2.utils.getSecsFromHHMMSS(time.substr(11, 8));
      }
      return 0;
    },

    getTotalTimeAsSeconds : function (time) {
      if (time.length > 0) {
        return rg2.utils.formatSecsAsMMSS(parseInt(time[0].textContent, 10));
      }
      return 0;
    },

    extractIOFV3Results : function (resultlist, result) {
      var k, finishtime, splitlist;
      for (k = 0; k < resultlist.length; k += 1) {
        result.chipid = rg2.utils.extractTextContentZero(resultlist[k].getElementsByTagName('ControlCard'), 0);
        result.position = rg2.utils.extractTextContentZero(resultlist[k].getElementsByTagName('Position'), '');
        result.status = rg2.utils.extractTextContentZero(resultlist[k].getElementsByTagName('Status'), '');
        // assuming first <Time> is the total time...
        // this one is in seconds and might even have tenths...
        result.time = this.getTotalTimeAsSeconds(resultlist[k].getElementsByTagName('Time'));
        result.starttime = this.getStartFinishTimeAsSeconds(rg2.utils.extractTextContentZero(resultlist[k].getElementsByTagName('StartTime'), 0));
        result.splits = "";
        result.codes = [];
        splitlist = resultlist[k].getElementsByTagName('SplitTime');
        result.controls = splitlist.length;
        this.extractIOFV3Splits(splitlist, result);
        finishtime = this.getStartFinishTimeAsSeconds(rg2.utils.extractTextContentZero(resultlist[k].getElementsByTagName('FinishTime'), 0));
        result.splits += finishtime - result.starttime;
      }
    },

    extractIOFV3Splits : function (splitlist, result) {
      var x;
      for (x = 0; x < splitlist.length; x += 1) {
        if (x > 0) {
          result.splits += ";";
        }
        result.splits += rg2.utils.extractTextContentZero(splitlist[x].getElementsByTagName('Time'), 0);
        result.codes[x] = rg2.utils.extractTextContentZero(splitlist[x].getElementsByTagName('ControlCode'), 'X' + x);
      }
      // add finish split
      result.splits += ";";
    }
  };
  rg2.ResultParserIOFV3 = ResultParserIOFV3;
}());
@@ -3635,52 +3635,8 @@
 ');%0A
-        result.controls = splitlist.length;%0A
     
@@ -3817,32 +3817,64 @@
 ishTime'), 0));%0A
+        if (finishtime %3E 0) %7B%0A  
         result.s
@@ -3913,16 +3913,73 @@
 rttime;%0A
+        %7D else %7B%0A          result.splits += 0;%0A        %7D%0A
       %7D%0A
@@ -4053,16 +4053,41 @@
    var x
+, codes;%0A      codes = %5B%5D
 ;%0A      
@@ -4142,63 +4142,201 @@
     
-if (x %3E 0) %7B%0A          result.splits += %22;%22;%0A        %7D%0A
+// only possible attributes are %22Missing%22 and %22Additional%22 so%0A        // if splitlist has attributes it is invalid and needs to be ignored%0A        if (splitlist%5Bx%5D.attributes.length === 0) %7B%0A  
     
@@ -4448,26 +4448,21 @@
     
-result.codes%5Bx%5D = 
+  codes.push(
 rg2.
@@ -4548,24 +4548,25 @@
 'X' + x)
+)
 ;%0A      
 %7D%0A      
@@ -4561,35 +4561,79 @@
     
-%7D%0A      // add finish split
+    result.splits += %22;%22;%0A        %7D%0A      %7D%0A      result.codes = codes;
 %0A   
@@ -4638,37 +4638,54 @@
      result.
-split
+control
 s 
-+
 = 
-%22;%22
+result.codes.length
 ;%0A    %7D%0A  %7D;
@@ -4735,8 +4735,9 @@
 3;%0A%7D());
+%0A

Improve IOF V3 results handling