package com.uvigo.mhp.looks;

import java.awt.*;
import java.awt.image.*;
import java.beans.*;
import org.havi.ui.*;
import org.dvb.ui.*;

// Documentar lo de widgetChanged!!!
public class HRangeLook1 extends HRangeLook
{
    private int imgX,imgY;
    private int imgWidth,imgHeight;
    private int pos;
    private int temp[];
    private int alpha;
    private boolean useGraphicContent;
    private int thumbSize; //lado del cuadrado que se pinta si no hay imagenes
    private PropertyChangeSupport changes;
    
    public HRangeLook1()
    {
        temp=new int[1];
        useGraphicContent=true;
        thumbSize=20;
        changes=new PropertyChangeSupport(this);
    }
    
    public boolean getUseGraphicContent()
    {
        return useGraphicContent;
    }
    
    public void setUseGraphicContent(boolean ugc)
    {
        boolean old=useGraphicContent;
        useGraphicContent=ugc;
        if (changes!=null)
            changes.firePropertyChange("useGraphicContent", old, ugc);
    }
    
    public int getThumbSize()
    {
        return thumbSize;
    }
    
    public void setThumbSize(int ts)
    {
        if (ts<=0) return;
        int old=thumbSize;
        thumbSize=ts;
        if (changes!=null)
            changes.firePropertyChange("thumbSize", old, ts);
    }
    
    public synchronized Dimension getPreferredSize(HVisible visible)
    {
        if (!(visible instanceof HStaticRange)) return null;
        
        HStaticRange hsr=(HStaticRange) visible;
        int min=hsr.getMinValue();
        int max=hsr.getMaxValue();
        int range=max-min;
        
        Image img=visible.getGraphicContent(visible.getInteractionState());
        if ((img!=null) && (useGraphicContent))
        {
            imgWidth=img.getWidth(null);
            imgHeight=img.getHeight(null);
        }
        else
        {
            imgWidth=thumbSize;
            imgHeight=thumbSize;
        }
        
        switch (hsr.getOrientation())
        {
            case HOrientable.ORIENT_LEFT_TO_RIGHT:
            case HOrientable.ORIENT_RIGHT_TO_LEFT:
            {
                return(new Dimension(imgWidth+2*range, imgHeight));
            }
            default: // ORIENT_TOP_TO_BOTTOM u ORIENT_BOTTOM_TO_TOP:
            {
                return(new Dimension(imgWidth, imgHeight+2*range));
            }
        }
    }
    
    public synchronized Dimension getMinimumSize(HVisible visible)
    {
        return getPreferredSize(visible);
    }
    
    public int hitTest(HAdjustmentValue component, Point pt)
    {
        HVisible cmp=(HVisible) component;
        Image img=cmp.getGraphicContent(cmp.getInteractionState());
        if ((img!=null) && (useGraphicContent))
        {
            imgWidth=img.getWidth(null);
            imgHeight=img.getHeight(null);
        }
        else
        {
            imgWidth=thumbSize;
            imgHeight=thumbSize;
        }
        
        double width=cmp.getSize().getWidth();
        int x=(int) pt.getX();
        int y=(int) pt.getY();
        if ((x>imgX) & (x<(imgX+imgWidth)) & (y>imgY) & (y<(imgY+imgHeight)))
        {
            if ((img==null)||(!useGraphicContent))
                return HAdjustableLook.ADJUST_THUMB;
            
            // Se pulsa en la zona donde se pinta la imagen
            PixelGrabber pg=new PixelGrabber(img, x-imgX, y-imgY, 1, 1, temp, 0, imgWidth);
            try
            {
                pg.grabPixels();
            }
            catch (InterruptedException ex)
            {
                new Exception("Error al obtener los pixels de una imagen").printStackTrace();
            }
            if ((pg.getStatus() & ImageObserver.ABORT) != 0)
            {
                new Exception("Error al obtener los pixels de una imagen").printStackTrace();
            }
            
            alpha=temp[0] & 0xff000000;
            if (alpha!=0)
                return HAdjustableLook.ADJUST_THUMB;
        }
        
        switch (component.getOrientation())
        {
            case HOrientable.ORIENT_LEFT_TO_RIGHT:
            {
                if(x<imgX)
                    return(HAdjustableLook.ADJUST_PAGE_LESS);
                if(x>imgX+imgWidth)
                    return(HAdjustableLook.ADJUST_PAGE_MORE);
                return(HAdjustableLook.ADJUST_NONE);
            }
            case HOrientable.ORIENT_RIGHT_TO_LEFT:
            {
                if(x<imgX)
                    return(HAdjustableLook.ADJUST_PAGE_MORE);
                if(x>imgX+imgWidth)
                    return(HAdjustableLook.ADJUST_PAGE_LESS);
                return(HAdjustableLook.ADJUST_NONE);
            }
            case HOrientable.ORIENT_TOP_TO_BOTTOM:
            {
                if(y<imgY)
                    return(HAdjustableLook.ADJUST_PAGE_LESS);
                if(y>imgY+imgHeight)
                    return(HAdjustableLook.ADJUST_PAGE_MORE);
                return(HAdjustableLook.ADJUST_NONE);
            }
            default: //HOrientable.ORIENT_BOTTOM_TO_TOP:
            {
                if(y<imgY)
                    return(HAdjustableLook.ADJUST_PAGE_MORE);
                if(y>imgY+imgHeight)
                    return(HAdjustableLook.ADJUST_PAGE_LESS);
                return(HAdjustableLook.ADJUST_NONE);
            }
        }
    }
    
    public void widgetChanged(HVisible visible, HChangeData[] changes)
    {
        if (!(visible instanceof HStaticRange)) return;
        
        HStaticRange hsr=(HStaticRange) visible;
        int min=hsr.getMinValue();
        int max=hsr.getMaxValue();
        int val=min;
        Dimension dim=hsr.getSize();
        
        if (changes==null) return;
        for (int i=0;i<changes.length;i++)
        {
            HChangeData change=changes[i];
            
            switch (change.hint)
            {
                case 1: // el objeto data se refiere a un punto donde se situa el raton
                    if (!(change.data instanceof Point)) break;
                    Point pt=(Point) change.data;
                    switch (hsr.getOrientation())
                    {
                        case HOrientable.ORIENT_LEFT_TO_RIGHT:
                            val+=(int) (((float) pt.x)/(float) dim.width*(float) (max-min));
                            hsr.setValue(val);
                            break;
                        case HOrientable.ORIENT_RIGHT_TO_LEFT:
                            val+=(int) (((float) (dim.width-pt.x))/(float) dim.width*(float) (max-min));
                            hsr.setValue(val);
                            break;
                        case HOrientable.ORIENT_TOP_TO_BOTTOM:
                            val+=(int) (((float) pt.y)/(float) dim.height*(float) (max-min));
                            hsr.setValue(val);
                            break;
                        default: // HOrientable.ORIENT_BOTTOM_TO_TOP:
                            val+=(int) (((float) (dim.height-pt.y))/(float) dim.height*(float) (max-min));
                            hsr.setValue(val);
                            break;
                    }
                    break;
                default:
                    visible.repaint();
                    break;
            }
        }
    }
    
    public void showLook(Graphics g, HVisible visible, int state)
    {
        HStaticRange hr;
        Dimension dim = visible.getSize();
        hr=(HStaticRange)visible;
        Image img=hr.getGraphicContent(state);
        if ((img!=null) && (useGraphicContent))
        {
            imgWidth=img.getWidth(null);
            imgHeight=img.getHeight(null);
        }
        else
        {
            imgWidth=thumbSize;
            imgHeight=thumbSize;
        }
        
        if (g instanceof DVBGraphics)
        {
            DVBGraphics g2=(DVBGraphics) g;
            DVBAlphaComposite a=DVBAlphaComposite.getInstance(DVBAlphaComposite.SRC_OVER);
            try
            {
                g2.setDVBComposite(a);
            }
            catch(Exception e)
            {
                new Exception("No se puede aplicar la regla de composici�n").printStackTrace();
            }
        }
        
        if (hr.getBackgroundMode()==HVisible.BACKGROUND_FILL)
        {
            g.setColor(visible.getBackground());
            g.fill3DRect(0,0,dim.width,dim.height,true);
        }
        g.setColor(visible.getForeground().darker());
        
        int min=hr.getMinValue();
        int max=hr.getMaxValue();
        int cur=hr.getValue();
        float pos=(float)(cur-min)/(float)(max-min);
        
        switch (hr.getOrientation())
        {
            case HOrientable.ORIENT_LEFT_TO_RIGHT:
            {
                imgX=(int) (pos*dim.width);
                imgX-=(imgWidth/2);
                imgY=dim.height/2-(imgHeight/2);
                
                g.drawLine(0, dim.height/2,dim.width,dim.height/2);
                break;
            }
            case HOrientable.ORIENT_RIGHT_TO_LEFT:
            {
                imgX=dim.width-(int) (pos*dim.width);
                imgX-=(imgWidth/2);
                imgY=dim.height/2-(imgHeight/2);
                
                g.drawLine(0, dim.height/2,dim.width,dim.height/2);
                break;
            }
            case HOrientable.ORIENT_TOP_TO_BOTTOM:
            {
                imgY=(int) (pos*dim.height);
                imgY-=(imgHeight/2);
                imgX=dim.width/2-(imgWidth/2);
                
                g.drawLine(dim.width/2,0,dim.width/2,dim.height);
                break;
            }
            default: // HOrientable.ORIENT_BOTTOM_TO_TOP
            {
                imgY=dim.height - (int) (pos*dim.height);
                imgY-=(imgHeight/2);
                imgX=dim.width/2-(imgWidth/2);
                
                g.drawLine(dim.width/2,0,dim.width/2,dim.height);
                break;
            }
        }
        
        if ((img!=null) && (useGraphicContent))
            g.drawImage(img, imgX, imgY, null);
        else
            g.fill3DRect(imgX, imgY, thumbSize, thumbSize, true);
    }
}
