//
// $Id: OrientableImageSprite.java,v 1.2 2004/10/15 00:14:23 andrzej Exp $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.media.sprite;

import java.awt.Graphics2D;
import java.awt.Rectangle;

import java.awt.geom.AffineTransform;
import java.awt.geom.Area;

import java.awt.image.*;

import com.threerings.media.image.Mirage;

import com.threerings.media.util.MultiFrameImage;

/**
 * An image sprite that uses AWT's rotation methods to render itself in
 * different orientations.
 */
public class OrientableImageSprite extends ImageSprite
{
    /**
     * Creates a new orientable image sprite.
     */
    public OrientableImageSprite ()
    {}
    
    /**
     * Creates a new orientable image sprite.
     *
     * @param image the image to render
     */
    public OrientableImageSprite (Mirage image)
    {
        super(image);
    }
    
    /**
     * Creates a new orientable image sprite.
     *
     * @param frames the frames to render
     */
    public OrientableImageSprite (MultiFrameImage frames)
    {
        super(frames);
    }
    
    /**
     * Computes and returns the rotation transform for this
     * sprite.
     *
     * @return the newly computed rotation transform
     */ 
    private AffineTransform getRotationTransform ()
    {
        double theta;
        
        switch(_orient)
        {
            case NORTH:
            default:
                theta = 0.0;
                break;
            
            case SOUTH:
                theta = Math.PI;
                break;
                    
            case EAST:
                theta = -Math.PI*0.5;
                break;
                
            case WEST:
                theta = Math.PI*0.5;
                break;
                
            case NORTHEAST:
                theta = -Math.PI*0.25;
                break;
            
            case NORTHWEST:
                theta = Math.PI*0.25;
                break;
                
            case SOUTHEAST:
                theta = -Math.PI*0.75;
                break;
                
            case SOUTHWEST:
                theta = Math.PI*0.75;
                break;
                
            case NORTHNORTHEAST:
                theta = Math.PI*0.125;
                break;
                
            case NORTHNORTHWEST:
                theta = -Math.PI*0.125;
                break;
                
            case SOUTHSOUTHEAST:
                theta = Math.PI*0.875;
                break;
                
            case SOUTHSOUTHWEST:
                theta = -Math.PI*0.875;
                break;
                
            case EASTNORTHEAST:
                theta = Math.PI*0.375;
                break;
                
            case EASTSOUTHEAST:
                theta = Math.PI*0.625;
                break;
                
            case WESTNORTHWEST:
                theta = -Math.PI*0.375;
                break;
                
            case WESTSOUTHWEST:
                theta = -Math.PI*0.625;
                break;
        }
        
        return AffineTransform.getRotateInstance(
            theta,
            (_ox - _oyoff) + _frames.getWidth(_frameIdx)/2,
            (_oy - _oyoff) + _frames.getHeight(_frameIdx)/2
        );
    }
    
    // Documentation inherited.
    protected void accomodateFrame (int frameIdx, int width, int height)
    {
        Area area = new Area(
            new Rectangle(
                (_ox - _oxoff),
                (_oy - _oyoff),
                width,
                height
            )
        );
        
        area.transform(getRotationTransform());
        
        _bounds = area.getBounds();
    }
    
    // Documentation inherited.
    public void setOrientation (int orient)
    {
        super.setOrientation(orient);
        
        layout();
    }
    
    // Documentation inherited.
    public void paint (Graphics2D graphics)
    {
        AffineTransform at = graphics.getTransform();
        
        graphics.transform(getRotationTransform());
        
        if(_frames != null) {
            _frames.paintFrame(
                graphics, 
                _frameIdx, 
                _ox - _oxoff, 
                _oy - _oyoff
            );
        }
        else {
            super.paint(graphics);
        }
        
        graphics.setTransform(at);
    }
}

@@ -35,17 +35,17 @@
 ava,v 1.
-2
+3
  2004/10
@@ -55,12 +55,12 @@
  00:
-14:2
+59:5
 3 an
@@ -2466,33 +2466,32 @@
         theta = 
--
 Math.PI*0.5;%0A   
@@ -2479,32 +2479,32 @@
  = Math.PI*0.5;%0A
+
                 
@@ -2566,32 +2566,33 @@
         theta = 
+-
 Math.PI*0.5;%0A   
@@ -2672,33 +2672,32 @@
         theta = 
--
 Math.PI*0.25;%0A  
@@ -2774,32 +2774,33 @@
         theta = 
+-
 Math.PI*0.25;%0A  
@@ -2881,33 +2881,32 @@
         theta = 
--
 Math.PI*0.75;%0A  
@@ -2987,32 +2987,33 @@
         theta = 
+-
 Math.PI*0.75;%0A  
@@ -3099,32 +3099,33 @@
         theta = 
+-
 Math.PI*0.125;%0A 
@@ -3212,33 +3212,32 @@
         theta = 
--
 Math.PI*0.125;%0A 
@@ -3324,32 +3324,33 @@
         theta = 
+-
 Math.PI*0.875;%0A 
@@ -3437,33 +3437,32 @@
         theta = 
--
 Math.PI*0.875;%0A 
@@ -3548,32 +3548,33 @@
         theta = 
+-
 Math.PI*0.375;%0A 
@@ -3660,32 +3660,33 @@
         theta = 
+-
 Math.PI*0.625;%0A 
@@ -3772,33 +3772,32 @@
         theta = 
--
 Math.PI*0.375;%0A 
@@ -3859,32 +3859,32 @@
  WESTSOUTHWEST:%0A
+
                 
@@ -3883,33 +3883,32 @@
         theta = 
--
 Math.PI*0.625;%0A 

I had the orientations backwards.