/* 
Copyright 2009 Allan Tokuda and David Orozco

This file is part of PatentPiler.

PatentPiler is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

PatentPiler is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with PatentPiler.  If not, see <http://www.gnu.org/licenses/>.
*/



function ClaimSet(claimText) {

    var claims=claimText.split(/<BR><BR>\s*[0-9]+\.\s*/g);
    var diff1=0;
    var diff2=0;
    var subclass;
    var showPreamble=true;

    /* convert strings into claim objects */
    for (i in claims) { claims[i] = new Claim(claims[i]); }

    this.constructHTML=function() {
        var out = "";
        if(claims.length==1) alert('There are no claims.');
        for (c=1; c<=claims.length-1; c++) {

            if (claims[c].selected()) {

                if      (c==diff1) subclass=" diff1";
                else if (c==diff2) subclass=" diff2";
                else               subclass="";

                if(claims[c].parentClaim() == null)
                    out+='<div class="indep'+subclass+'" id="claim'+c+'">'+
                         '<div class="head"><h3>'+ c + ' &mdash; Independent &mdash; '+claims[c].type()+'</h3>';
                else
                    out+='<div class="dep'+subclass+'" id="claim'+c+'">'+
                         '<div class="head"><h3>'+ c + '</h3>'+
                         '<span class="dep_ref">(Dependent on ' + claims[c].parentClaim() + ')</span>';

                out+='<span class="difflinks">';

                if(c==diff1 || c==diff2)
                    out+=    '<a href="javascript:diffreset()">Cancel compare</a>';
                else if (c!=diff1 && diff1!=0)
                    out+=    '<a href="javascript:diff2set('+c+')">Compare to claim '+diff1+'</a>';
                else
                    out+=    '<a href="javascript:diff1set('+c+')">Compare to other claims</a>';


                out+='</span></div><div class="body">';


                if (c==diff2)
                    out+=    diffString(claims[diff1].toString(showPreamble), claims[c].toString(showPreamble));
                else if (c==diff1 && diff2!=0)
                    out+=    diffString(claims[diff2].toString(showPreamble), claims[diff1].toString(showPreamble));
                else
                    out+=    claims[c].toString(showPreamble);

                out+=    '</div>\n</div>\n';
            }

        }
        return out;
    }

    this.controllerHTML=function() {
        var out = "";

        if (!showPreamble) out+='<a href="javascript:preambleOn()">Show/hide dependent claim preambles</a>';
        else               out+='<a href="javascript:preambleOff()">Show/hide dependent claim preambles</a>';

        return out;
    }

    /* I would have done the recursive approach but then children would have to talk to each other */
    function depth (claim_num) {

        if (claim_num < claims.length);
        for (d=0; d<claims.length && claims[claim_num].parentClaimText() != "Independent"; d++)
            claim_num=claims[claim_num].parentClaim();

        return d;
    }

    this.diff1=function(c) { diff1 = c; }
    this.diff2=function(c) { diff2 = c; }
    this.nodiff=function() { diff1 = 0; diff2 = 0; }
    this.preambleToggle=function() { showPreamble=!showPreamble;  }
    this.preambleOn =function() { showPreamble=true;  }
    this.preambleOff=function() { showPreamble=false; }

    this.selectType=function(claimType){ for (c in claims) claims[c].selectIfType(claimType); }

}

function Claim(claimText) {

    var words  = claimText.split(/\s+/g);
    var spaces = claimText.match(/\s+/g);
    var parentClaim;
    var claimRefPos=0;
    var preambleLength=0;
    var selected = true;

    /* find claim reference, which would make this instance a dependent */
    var word_prev=""
    for (w in words) {
        if (word_prev == "claim" && words[w].search(/[0-9]/) == 0) {
            claimRefPos = parseInt(w);
            parentClaim=words[w].match(/[0-9]+/);
            break;
        }
        word_prev=words[w];
    }

    /* find preamble ending, which is either at the claim reference, 
     or a couple words later, or sometimes it does not exist if the 
     claim reference is at the end of the claim. */

    
    if (claimRefPos > words.length - 5)
        preambleLength = 0

    else if (words[claimRefPos+1].search(/wherein/) != -1)
        preambleLength = claimRefPos+1;
            
    else if (words[claimRefPos+1].search(/further/) != -1 && (
                words[claimRefPos+2].search(/comprising/) != -1 ||
                words[claimRefPos+2].search(/including/ ) != -1 ))
        preambleLength = claimRefPos+2;
    else
        preambleLength = claimRefPos;


    var type = "Product";
    /* product/article of manufacture is the default; the following would override this: */
    if(claimText.search(/\b(?:process|method|procedure)\b/                )>-1) type="Process";
    if(claimText.search(/\b(?:machine|system|apparatus|network)\b/        )>-1) type="Machine";
    if(claimText.search(/\b(?:composition|compound|mixture|formulation)\b/)>-1) type="Composition";
    if(claimText.search(/\b(?:introduction)\b/                            )>-1) type="Introduction";

    this.toString = function(showPreamble) {
        var str="";

        if (showPreamble && preambleLength > 0) str+='<p class="preamble">'

        for (w in spaces) {
            str+=words[w]+spaces[w];
            if (preambleLength > 0 && w == preambleLength) 
                if (showPreamble) str+='</p>'
                else str="";
        }
        str+=words[words.length-1];
        str=str.replace(/;/g,";<br><br>");

        return str;
    }


    this.parentClaim = function() { return parentClaim; }
    this.type        = function() { return type; }

    this.depth = function() {
        if (parentClaim == null) return 0;
        else                     return parent.depth(parentClaim)+1;

        /* for clarification: "parent" is a ClaimSet, whereas "parentClaim" is another Claim. */
    }

    this.select   = function()            { selected=true;  }
    this.deselect = function()            { selected=false; }
    this.selected = function()            { return selected; }

    this.selectIfType = function(claimType) { 
        if      (claimType == "All"  )       selected=true; 
        else if (claimType == "Independent") selected=(parentClaim == null); 
        else                                 selected=(  claimType == type); 
    }
}

function splitPatent(patentHTML) {

    var wanted;
    var title;
    var claims=new Array();
    var disclosure;
    var parts=new Array();

    parts=patentHTML.split(/<font size="\+1">/);
    title=parts[1];
    parts=title.split(/<\/font>/);
    title=parts[0];

    parts=patentHTML.split(/<HR>\s*<CENTER>\s*<B>\s*<I>\s*Claims\s*<\/B>\s*<\/I>\s*<\/CENTER>\s*<HR>/);
    wanted=parts[1];
    parts=wanted.split(/<HR>\s*<CENTER>\s*<B>\s*<I>\s*Description\s*<\/B>\s*<\/I>\s*<\/CENTER>\s*<HR>/);
    claims=new ClaimSet(parts[0]);
    disclosure=parts[1];

    return { title: title, claims: claims, disclosure: disclosure };
}
