package introspection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Exercice(4)
public class ProxyFraction implements Fraction {

	private ConcreteFraction cf;
	
	public ProxyFraction(ConcreteFraction f){
		cf=f;
	}
	
	private Object runMethod(String name, Class<?>[] param,Object[] args){
		Method m=null;
		try{
			m=ConcreteFraction.class.getMethod(name, param);
		}catch(NoSuchMethodException e){};
		// Pre traitement 
		System.out.println("Appel de "+name);
		//
		Object o=null;
		try{
			o=m.invoke(cf,args);
		}
		catch(InvocationTargetException e){}
		catch(IllegalAccessException e){}
		// Post traitement 
		System.out.println("Fin de "+name);
		//
		return o;
	}
	
	
	@Override
	public Fraction addTo(Fraction f) {
		Class<?>[] param={Fraction.class};
		Object[] args={f};
		return (Fraction)runMethod("addTo",param, args);
	}

	@Override
	public Fraction divBy(Fraction f) {
		Class<?>[] param={Fraction.class};
		Object[] args={f};
		return (Fraction)runMethod("divBy",param, args);
	}

	@Override
	public int getDenominator() {
		Class<?>[] param={};
		Object[] args={};
		return (Integer)runMethod("getDenominator",param, args);
	}

	@Override
	public int getNumerator() {
		Class<?>[] param={};
		Object[] args={};
		return (Integer)runMethod("getNumerator",param, args);
	}

	@Override
	public Fraction inverse() {
		Class<?>[] param={};
		Object[] args={};
		return (Fraction)runMethod("inverse",param, args);
	}

	@Override
	public Fraction multTo(Fraction f) {
		Class<?>[] param={Fraction.class};
		Object[] args={f};
		return (Fraction)runMethod("multTo",param, args);
	}

	@Override
	public Fraction opposite() {
		Class<?>[] param={};
		Object[] args={};
		return (Fraction)runMethod("opposite",param, args);
	}

	@Override
	public void setDenominator(int d) {
		Class<?>[] param={int.class};
		Object[] args={d};
		runMethod("opposite",param, args);
	}

	@Override
	public void setNumerator(int n) {
		Class<?>[] param={int.class};
		Object[] args={n};
		runMethod("opposite",param, args);
	}

	@Override
	public Fraction subTo(Fraction f) {
		Class<?>[] param={Fraction.class};
		Object[] args={f};
		return (Fraction)runMethod("subTo",param, args);
	}

	@Override
	public String toString() {
		Class<?>[] param={};
		Object[] args={};
		return (String)runMethod("toString",param, args);
	}

}
