export class EasyCalc {
    //Atributos
    private result:number;          //Guarda el resultado del cálculo
    private historial:number[];   //Guarda una lista con los últimos resultados
    private formatos:string[];    //Guarda 'result' en otros formatos
    
    //Constructor. Guarda un valor en el atributo 'result', inicializa
    //el pool de 'result' y codifica 'result' en otros formatos
    constructor (result:number=0) {
        this.result=result;
        this.historial=[];
        this.formatos=new Array(4);
        this.actualizarFormatos();        
    }
    //Actualización de la propiedad 'resultPool'
    private actualizarHistorial() {
        this.historial.push(this.result);
    }
    //Actualización de la propiedad 'resultCode'
    private actualizarFormatos() {
        this.formatos[0]=this.result.toString(2);        
        let res:string=this.result.toString();
        let ascii:string="";
        for (let i=0;i<res.length;i++) {
            ascii+=res.charCodeAt(i)+"-";
        }
        this.formatos[1]=ascii.substring(0,ascii.length-1);        
        this.formatos[2]=this.result.toString(16);
        this.formatos[3]=this.result.toExponential();
    }
    //Resetear todos los atributos resultado
    public refresh() {
        this.result=0;
        this.historial=[];
        this.formatos=new Array(4);
        this.actualizarFormatos();
    }

    //Métodos get
    public getResult():number {
        return this.result;
    }

    public getHistorial():number[] {
        let resultado:number[]=[];
        if (this.historial) {
            resultado=this.historial;
        }
        return resultado;      
    }

    public getFormatos():string[] {
        return this.formatos;
    }
    //Operaciones de suma, resta, multiplicación, división y porcentaje
    public suma(numeros:number[]):number {
        let res:number=0;
        if (numeros) {
            for(let i=0;i<numeros.length;res+=numeros[i++]);            
        }
        this.result=res;
        this.actualizarFormatos();
        this.actualizarHistorial();
        return res;
    }

    public resta(numeros:number[]):number {
        let res:number=0;
        if (numeros) {
            res=numeros[0];
            for(let i=1;i<numeros.length;res-=numeros[i++]);
        }
        this.result=res;
        this.actualizarFormatos();
        this.actualizarHistorial();
        return res;
    }

    public mult(numeros:number[]):number {
        let res:number=0;
        if (numeros) {
            res=1;
            for(let i=0;i<numeros.length;res*=numeros[i++]);
        }
        this.result=res;
        this.actualizarFormatos();
        this.actualizarHistorial();
        return res;
    }

    public div(numeros:number[]):number {
        let res:number=0;
        if (numeros) {
            res=numeros[0];
            for(let i=1;i<numeros.length;res/=numeros[i++]);
        }
        this.result=res;
        this.actualizarFormatos();
        this.actualizarHistorial();
        return res;
    }

    public percent(numero:number,porcentaje:number,op:string="") {
        let res:number=0;
        switch (op) {
            case "+":
                res=numero*(1+porcentaje/100);
                break;
            case "-":
                res=numero*(1-porcentaje/100);
                break;
            default:
                res=numero*(porcentaje/100);
        }
        this.result=res;
        this.actualizarFormatos();
        this.actualizarHistorial();
        return res;
    }
    //Métodos estáticos de suma, resta, multiplicación, división y porcentaje
    static suma(numeros:number[]):number {
        let res:number=0;
        for(let i=0;i<numeros.length;res+=numeros[i++]);       
        return res;
    }

    static resta(numeros:number[]):number {
        let res:number=numeros[0];
        for(let i=1;i<numeros.length;res-=numeros[i++]);        
        return res;
    }

    static mult(numeros:number[]):number {
        let res:number=1;
        for(let i=0;i<numeros.length;res*=numeros[i++]);
        return res;
    }

    static div(numeros:number[]):number {
        let res:number=numeros[0];
        for(let i=1;i<numeros.length;res/=numeros[i++]);        
        return res;
    }

    static percent(numero:number,porcentaje:number,op:string="") {
        let res:number=0;
        switch (op) {
            case "+":
                res=numero*(1+porcentaje/100);
                break;
            case "-":
                res=numero*(1-porcentaje/100);
                break;
            default:
                res=numero*(porcentaje/100);
        }        
        return res;
    }
}