package MSlider;
/* (swing1.1.1) */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;



/**
 * @version 1.0 09/08/99
 */
public class MThumbSliderAdditionalUI {
  
  MThumbSlider  mSlider;
  BasicSliderUI ui;
  Rectangle[]   thumbRects;
  int           thumbNum;
  private transient boolean isDragging;
  Icon thumbRenderer;
  
  Rectangle trackRect;
  
  ChangeHandler changeHandler;
  TrackListener trackListener;
  

  
  public MThumbSliderAdditionalUI(BasicSliderUI ui)   {
    this.ui      = ui;
  }

  
  public void installUI(JComponent c)   {
    mSlider    = (MThumbSlider)c;
    thumbNum   = mSlider.getThumbNum();
    thumbRects = new Rectangle[thumbNum];
    for (int i=0; i<thumbNum; i++) {
      thumbRects[i] = new Rectangle();
    }
    isDragging = false;
    trackListener = new MThumbSliderAdditionalUI.TrackListener(mSlider);
    changeHandler = new ChangeHandler();
  }
  
  public void uninstallUI(JComponent c) {
    thumbRects = null;
    trackListener = null;
    changeHandler = null;
  }
  
      
  protected void calculateThumbsSize() {
    Dimension size = ((MThumbSliderAdditional)ui).getThumbSize();
    for (int i=0; i<thumbNum; i++) {
      thumbRects[i].setSize( size.width, size.height );
    }
  }
  
    
  protected void calculateThumbsLocation() {
    for (int i=0; i<thumbNum; i++) {
      if ( mSlider.getSnapToTicks() ) {
        int tickSpacing = mSlider.getMinorTickSpacing();	    
        if (tickSpacing == 0) {
          tickSpacing = mSlider.getMajorTickSpacing();
        }
        if (tickSpacing != 0) {      
          int sliderValue  = mSlider.getValueAt(i);           
          int snappedValue = sliderValue; 
          //int min = mSlider.getMinimumAt(i);                           
          int min = mSlider.getMinimum();                          
          if ( (sliderValue - min) % tickSpacing != 0 ) {
            float temp = (float)(sliderValue - min) / (float)tickSpacing;
            int whichTick = Math.round( temp );
            snappedValue = min + (whichTick * tickSpacing);            
            mSlider.setValueAt( snappedValue , i);           
          }
        }
      }	
      trackRect = getTrackRect(); 	
      if ( mSlider.getOrientation() == JSlider.HORIZONTAL ) {
        int value = mSlider.getValueAt(i);
        int valuePosition = ((MThumbSliderAdditional)ui).xPositionForValue(value);
        thumbRects[i].x = valuePosition - (thumbRects[i].width / 2);
        thumbRects[i].y = trackRect.y;
        
      } else {
        int valuePosition = ((MThumbSliderAdditional)ui).yPositionForValue(mSlider.getValueAt(i));     // need
        thumbRects[i].x = trackRect.x;
        thumbRects[i].y = valuePosition - (thumbRects[i].height / 2);
      }
    }
  }
  
    
  public int getThumbNum() {
    return thumbNum;
  }
  
  public Rectangle[] getThumbRects() {
    return thumbRects;
  }
  
  
 

  private static Rectangle unionRect = new Rectangle();
  
  public void setThumbLocationAt(int x, int y, int index)  { 
    Rectangle rect = thumbRects[index];  
    unionRect.setBounds( rect );
    
    rect.setLocation( x, y );
    SwingUtilities.computeUnion( rect.x, rect.y, rect.width, rect.height, unionRect ); 
    mSlider.repaint( unionRect.x, unionRect.y, unionRect.width, unionRect.height );
  }
  
  
  public Rectangle getTrackRect() {
    return ((MThumbSliderAdditional)ui).getTrackRect();
  }
  
  
  
  
  public class ChangeHandler implements ChangeListener {
    public void stateChanged(ChangeEvent e) {
      if ( !isDragging ) {
        calculateThumbsLocation();
	mSlider.repaint();
      }
    }
  }
  
  
  
  public class TrackListener extends MouseInputAdapter {
    protected transient int offset;
    protected transient int currentMouseX, currentMouseY;
    protected Rectangle adjustingThumbRect = null;
    protected int adjustingThumbIndex;
    protected MThumbSlider   slider;
    protected Rectangle trackRect;
    
    TrackListener(MThumbSlider slider) {
      this.slider = slider;
    }
  
    public void mousePressed(MouseEvent e) {
      if ( !slider.isEnabled() ) {
        return; 
      }
      currentMouseX = e.getX();
      currentMouseY = e.getY();
      slider.requestFocus();

      for (int i=0; i<thumbNum; i++) {
        Rectangle rect = thumbRects[i];
        if ( rect.contains(currentMouseX, currentMouseY) ) {
          
          switch ( slider.getOrientation() ) {
            case JSlider.VERTICAL:
                 offset = currentMouseY - rect.y;
                 break;
            case JSlider.HORIZONTAL:
                 offset = currentMouseX - rect.x;
                 break;
          }
          isDragging = true;
          slider.setValueIsAdjusting(true);
          adjustingThumbRect = rect;
          adjustingThumbIndex = i;
          return;
        }
      }
    }
    
    public void mouseDragged( MouseEvent e ) {                    
      if ( !slider.isEnabled() 
                 || !isDragging 
                 || !slider.getValueIsAdjusting()
                 || adjustingThumbRect == null ) {
        return;
      }
      int thumbMiddle = 0;
      currentMouseX = e.getX();
      currentMouseY = e.getY();

      Rectangle rect = thumbRects[adjustingThumbIndex];
      trackRect = getTrackRect();      
      switch ( slider.getOrientation() ) {
        case JSlider.VERTICAL:      
          int halfThumbHeight = rect.height / 2;
          int thumbTop    = e.getY() - offset;
          int trackTop    = trackRect.y;
          int trackBottom = trackRect.y + (trackRect.height - 1);

          thumbTop = Math.max( thumbTop, trackTop    - halfThumbHeight );
          thumbTop = Math.min( thumbTop, trackBottom - halfThumbHeight );

          setThumbLocationAt(rect.x, thumbTop, adjustingThumbIndex);

          thumbMiddle = thumbTop + halfThumbHeight;
          mSlider.setValueAt( ui.valueForYPosition( thumbMiddle ) , adjustingThumbIndex);
          break;
          
        case JSlider.HORIZONTAL:
          int halfThumbWidth = rect.width / 2;
          int thumbLeft  = e.getX() - offset;
          int trackLeft  = trackRect.x;
          int trackRight = trackRect.x + (trackRect.width - 1);

          thumbLeft = Math.max( thumbLeft, trackLeft  - halfThumbWidth );
          thumbLeft = Math.min( thumbLeft, trackRight - halfThumbWidth );

          setThumbLocationAt( thumbLeft, rect.y, adjustingThumbIndex);

          thumbMiddle = thumbLeft + halfThumbWidth;
          mSlider.setValueAt( ui.valueForXPosition( thumbMiddle ), adjustingThumbIndex );          
          break;
      }
    }
    
    public void mouseReleased(MouseEvent e) {
      if ( !slider.isEnabled() ) {
        return;
      }
      offset = 0;
      isDragging = false;
      mSlider.setValueIsAdjusting(false);
      mSlider.repaint();
    }

    public boolean shouldScroll(int direction) {
      return false;
    }
    
  }
  
}