/**
 * TODO hicksian, cost function, indirect demand, 
 * Leontief, perfect substitutes
*/
/**
 * u = [x^p + y^p]^(1/p) where p = 1-(1/e)
*/
function CES( e, a ){
        this.a = a;
        this.e = e;
        this.p = 1.0 - ( 1.0 / e );
        this.r = this.p / ( this.p - 1.0 );
        
        this.setE = function( e ){
                this.e = e;
                this.p = 1.0 - ( 1.0 / e );
                this.r = this.p / ( this.p - 1.0 );  
        }
        
        this.getIndifferentY = function( u, x ){
                var up = Math.pow( u , this.p );
                var xp = this.a * Math.pow( x , this.p ); 
                var dp = ( up - xp )/( 1.0 - this.a );
                if( dp < 0.0 ){
                        return 9999999.99;
                }
                var y = Math.pow( dp , ( 1.0 / this.p ));
                return y;
        }
            
        /**
        * get the utility associated with x and y
        **/
        this.getUtility = function( x, y ){
                var u = this.a * Math.pow( x, this.p ) + 
                        ( 1.0 - this.a )*Math.pow( y , this.p );
                u = Math.pow( u , 1.0/this.p );
                return u;
        }
    
        this.getDemand = function ( px_py, income ){
                a = Math.pow( this.a / px_py, this.e );
                var b = income / ( Math.pow( this.a, this.e ) * 
                                   Math.pow( px_py, 1.0 - this.e ) + 
                                   Math.pow( 1-this.a, this.e ));
                var dx = a*b;
                return dx;
        }
}

/**
 * u = x**a * y **(1-a)
 * elasticity of substution = 1
*/
function CobbDouglas( a ){
        
        this.a = a;
        
        this.getIndifferentY = function( u, x ){
                var up = Math.pow( x , -1.0 * this.a );
                var y = Math.pow( up * u , ( 1.0 / ( 1.0-this.a )));
                return y;
        }
        
        this.getUtility = function( x, y ){
                var u = Math.pow( x , this.a ) * Math.pow( y , 1.0 - this.a );
                return u;
        }
        
        this.getDemand = function( px_py, income ){
                var x = this.a * income / px_py;
                return x;
        }
}

function Leontief( a ){
        // HELP!!
        
}

function getUtilityFunction( e, a ){
        if(( e > 0.99 ) && ( e < 1.01 )){
                return new CobbDouglas( a );       
        } else if(( e > -0.01 ) && ( e < 0.01 )){
                return new Leontief( e );    
        } else if( e < 1000.0 ){
                return new CES( e, a );       
        } else {
                // perfect substitutes       
        }
}
