/*******************************************************************************
* Copyright (c)                                                                *
*           2005   Tristan Allwood,                                            *
*           2005   Daniel Burke,                                               *
*           2005   Marc Hull,                                                  *
*           2005   Ekaterina Itskova,                                          *
*           2005   Steve Zymler                                                *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a      *
* copy of this software and associated documentation files (the                *
* "Software"), to deal in the Software without restriction, including          *
* without limitation the rights to use, copy, modify, merge, publish,          *
* distribute, sublicense, and/or sell copies of the Software, and to           *
* permit persons to whom the Software is furnished to do so, subject to        *
* the following conditions:                                                    *
*                                                                              *
* The above copyright notice and this permission notice shall be included      *
* in all copies or substantial portions of the Software.                       *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS      *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                   *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.       *
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY         *
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,         *
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE            *
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                       *
*******************************************************************************/
/*
 * Created on Dec 27, 2004
 */
package uk.ac.ic.doc.kevlar.core.programs.imageUtils;

import java.awt.Dimension;

/**
 * @author tora
 */
final class ImageEditScaler {

    private final Behaviour useBehaviour;
    
    private final double scaleWidth;
    private final double scaleHeight;
    
    private final int fixedWidth;
    private final int fixedHeight;

    private final boolean flip;
    
    
    private final Behaviour FF = new Behaviour() {

        public Dimension getNewDimension(Dimension original) {
            return new Dimension(fixedWidth,fixedHeight);
        }
        
    };
    
    private final Behaviour FS = new Behaviour() {

        public Dimension getNewDimension(Dimension original) {
            int left = getFixedLeft();
            double right = getRight(original);
            double scaleRight = getScaleRight();
            right *= scaleRight;
            System.err.println("FS" + left +" " + right);
            return makeDimension(left,right);
        }
        
    };
    
    
    private final Behaviour FN = new Behaviour() {

        public Dimension getNewDimension(Dimension original) {
            double left = getLeft(original);
            double right = getRight(original);
            double newLeft = getFixedLeft();
            right *= (newLeft / left);
            return makeDimension(getLeft(original),right);
        }
        
    };
    
    private final Behaviour SS = new Behaviour() {

        public Dimension getNewDimension(Dimension original) {
            return makeDimension(
                    getLeft(original) * getScaleLeft(),
                    getRight(original) * getScaleRight()
            );
        }
        
    };
    
    
    private final Behaviour SN = new Behaviour() {

        public Dimension getNewDimension(Dimension original) {
            return makeDimension(getLeft(original) * getScaleLeft(),getRight(original) * getScaleLeft());
        }
        
    };
    
    
    private final Behaviour[][] behaviours = {
            { FF, FS, FN },
            { FS, SS, SN },
            { FN, SN, null }
    };
    
    private final static boolean[][] flips = {
            { false, false, false },
            {true, false, false},
            {true,true, false}
    };
    
    ImageEditScaler(String width,String height) {
        if( width.equals("") && height.equals("") ) {
            scaleWidth = 1;
            scaleHeight = 1;
            fixedWidth = 0;
            fixedHeight = 0;
            useBehaviour = SS;
            flip = false;
            return;
        }
        
        int x;
        int y;
        
        if( width.matches("^\\d*\\.\\d*$")) {
            scaleWidth = Double.parseDouble(width);
            fixedWidth = -1;
            x = 1;
        } else if ( width.matches("^\\d+$")) {
            fixedWidth = Integer.parseInt(width);
            scaleWidth = -1;
            x = 0;
        } else if ( width.equals("")){
            scaleWidth = fixedWidth = -1;
            x = 2;
        } else {
            throw new IllegalArgumentException("Bad Width String");
        }
        
        if( height.matches("^\\d*\\.\\d*$") ){
            scaleHeight = Double.parseDouble(height);
            fixedHeight = -1;
            y = 1;
        } else if ( height.matches("^\\d+$")) {
            fixedHeight = Integer.parseInt(height);
            scaleHeight = -1;
            y = 0;
        } else if ( height.equals("")) {
            scaleHeight= -1;
            fixedHeight = -1;
            y = 2;
        } else {
            throw new IllegalArgumentException("Bad Height String");
        }
        
        useBehaviour = behaviours[x][y];
        flip = flips[x][y];
    }

    
    Dimension getNewDimension(Dimension original) {
        return useBehaviour.getNewDimension(original);
    }
    
    static interface Behaviour {
        Dimension getNewDimension(Dimension original);
    }
    
    private Dimension makeDimension( double left, double right ) {
        // oh god, tristan....
        return new Dimension( flip ? (int) right : (int) left , flip ? (int) left : (int) right );
    }
    
    private double getLeft( Dimension d ) {
        
        if (flip) {
            
            return d.getHeight();
            
        } else {
          
            return d.getWidth();
            
        }
        
    }
    
    private double getRight( Dimension d ) {

        if (flip) {
            
            return d.getWidth();
            
        } else {
          
            return d.getHeight();
            
        }
        
//        return flip ? d.getWidth() : d.getHeight();
    }
    
    private double getScaleLeft() {
        
        if (flip) {
            
            return scaleHeight;
            
        } else {
          
            return scaleWidth;
            
        }
        
//        return flip ? scaleHeight : scaleWidth;
    }
    
    private double getScaleRight() {
        
        if (flip) {
            
            return scaleWidth;
            
        } else {
          
            return scaleHeight;
            
        }
        
//        return flip ? scaleWidth : scaleHeight;
    }
    
    private int getFixedLeft() {
        
        if (flip) {
            
            return fixedHeight;
            
        } else {
          
            return fixedWidth;
            
        }
        
//        return flip ? fixedHeight : fixedWidth;    
    }
    
    private int getFixedRight() {
        
        if (flip) {
            
            return fixedWidth;
            
        } else {
          
            return fixedHeight;
            
        }
        
//        return flip ? fixedWidth : fixedHeight;
    }

}
    
 
