package helloworldapp;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author hdlea
 * This class should receive a string containing the term to be summed (examples: n^2, 1/n, 1/n^2), and the interval (example: 0 to 100)
 * then it should return the result. When possible it should simplify the sum. It also should be able to say if it is divergent or not and to calculate sums with no boundary when convergent.
 * //receives a string as the example: (X+2)/X^(0.5) FROM -INF TO 100
 */
public class Summation {
    private String lowerLimit;
    private String upperLimit;
    private String genericTerm;
    private char iteratingTerm;
    private double value;
    
    /**
     *
     */
    Summation(){
        lowerLimit = "0";
        upperLimit = "0";
        genericTerm = "x";
        iteratingTerm = 'x';
        value = 0;
    }
    
    //receives a string as the example: (X+2)/X^(0.5) FROM -INF TO 100
    //parses it and feed the attributes
    Summation(String input)
            throws IncorrectInputText
    {
        IncorrectInputText IncorrectInput = new IncorrectInputText();
        int control = 0; //checks if the input contains only one type letter (the iterating term)
        char aux;
        int i;
        String temp = new String();
        
        if(input.length()==0)
            throw (IncorrectInput);//throw exception if string is somehow empty
        
        //parses the string up to the first space, puts the result into the genericTerm, it also identifies the letter that we are using as iterating term for sum.
        for(i = 0; input.charAt(i) != 32; i++){
            genericTerm = genericTerm + input.charAt(i);
            
            //the follwing sequence of ifs checks for the letter and put it into the iteratingTerm. it throws an error if two different letters are found. Because it would be impossible to distinguish the iterating term among them
            if( (input.charAt(i)>=65 && input.charAt(i) <=90) || (input.charAt(i)>=97 && input.charAt(i) <=122) ){
                if(control >0){
                    aux = input.charAt(i);
                    if(aux != iteratingTerm)
                        throw (IncorrectInput);//found two different letters
                }//end if middle
                iteratingTerm = input.charAt(i);
                control++;
                         
            }//end if external
        }//end of for
        
        i++;//sums to get in the position of the next character after space
        
        for(i = i; input.charAt(i) != 32; i++){
            temp = temp + input.charAt(i);
        }//end of for
        if(!temp.equals("FROM")) {
            throw (IncorrectInput);//input format is incorrect, expected from word
        }//end of if
        
        i++;
        
        for(i = i; input.charAt(i) != 32; i++){
            lowerLimit = lowerLimit + input.charAt(i);
        }//end of for
        
        i++;
        temp = "";
        for(i = i; input.charAt(i) != 32; i++){
            temp = temp + input.charAt(i);
        }//end of for       
        if(!temp.equals("TO")) {
            throw (IncorrectInput);//input format is incorrect, expected from word
        }//end of if
        
        i++;
        for(i = i; i<input.length(); i++){
            upperLimit = upperLimit + input.charAt(i);
        }//end of for        
        
     //the following lines correct a NULL word that displays in the zero position. This happens because we are concatenating with an empty string
     lowerLimit = lowerLimit.substring(4);
     upperLimit = upperLimit.substring(4);
     genericTerm = genericTerm.substring(4);
        
    }//end of method
    
    public String checkSummation(){
        String line;
        line = "SUM "+genericTerm+" FROM "+lowerLimit+" TO "+upperLimit+" ";
        return (line);
    }
    
    //this method parses the string of the generic term
    //it gives back to the calling method one term each time it's called, this term is returned with it's proper type.
    private NewTypeContainer termParser(){
        int termLenght = genericTerm.length();
        String numbers = new String();
        String rest = new String();
        int auxNumber;
        NewTypeContainer result = new NewTypeContainer();
        int i;//this counter marks were we are in the string
        
        {//this block of code checks if the next element in the string is an integer. It parses it and put the rest of the string in "rest" variable.
            //checks for the first elements of the string, if they are integers they will be parsed int the following for and if
            for(i = 0; i<termLenght && (genericTerm.charAt(i)>=48 && genericTerm.charAt(i)<=57 ); i++)
                numbers = numbers + genericTerm.charAt(i);

            if(numbers.length() != 0){
                auxNumber = Integer.parseInt(numbers);
                result.setTypeOfElement("int");
                result.setElementInt(auxNumber);
            }//end of if (numbers.length() != 0)
            int j=i;
            for(i=j; i<termLenght; i++){
                rest = rest + genericTerm.charAt(i);
                result.setRestOfString(rest);
            }//end of for
        }//end of block
        
        
        return(result);
    }//end of method termParser
    
    //evaluate the sum value
    public double evaluateSum(){
        int lower, upper;
        
        //checks if upper and lower bounds are not infinity
        if(!"INF".equals(upperLimit.toUpperCase()) || !"-INF".equals(lowerLimit.toUpperCase())){
            
            lower = Integer.parseInt(lowerLimit);
            upper = Integer.parseInt(upperLimit);
            
            {//calls the method for parsing the generic term into smaller parts that can be adreesed
                
            
            }
        
            for(int i = lower; i <= upper; i++){
                value ++;
            }
        
        }//end of if (!"INF".equals(upperLimit.toUpperCase()) || !"-INF".equals(lowerLimit.toUpperCase()))
        return (value);
    }//end of method evaluateSum
    
}//end of class
