content: package com.group_finity.mascot.win;
  
  import java.awt.Graphics;
  
  import javax.swing.JWindow;
  
  import com.group_finity.mascot.image.NativeImage;
  import com.group_finity.mascot.image.TranslucentWindow;
  import com.group_finity.mascot.win.jna.BLENDFUNCTION;
  import com.group_finity.mascot.win.jna.Gdi32;
  import com.group_finity.mascot.win.jna.POINT;
  import com.group_finity.mascot.win.jna.RECT;
  import com.group_finity.mascot.win.jna.SIZE;
  import com.group_finity.mascot.win.jna.User32;
  import com.sun.jna.Native;
  import com.sun.jna.Pointer;
  
  /**
   * The image window with alpha.
   * {@link #setImage(WindowsNativeImage)} set in {@link WindowsNativeImage} can be displayed on the desktop.
   * 
   * {@link #setAlpha(int)} may be specified when the concentration of view.
   *
   * Original Author: Yuki Yamada of Group Finity (http://www.group-finity.com/Shimeji/)
   * Currently developed by Shimeji-ee Group.
   */
  class WindowsTranslucentWindow extends JWindow implements TranslucentWindow {
  
  	private static final long serialVersionUID = 1L;
      
      private boolean alwaysOnTop = false;
  	
  	@Override
  	public JWindow asJWindow() {
  		return this;
  	}
  
  	/**
  	 * Draw a picture with a value of alpha.
  	 * @param imageHandle bitmap handle.
  	 * @param alpha concentrations shown. 0 = not at all, 255 = full display.
  	 */
  	private void paint(final Pointer imageHandle, final int alpha) {
  		
  		final Pointer hWnd = Native.getComponentPointer(this);
  		
  		if ( User32.INSTANCE.IsWindow(hWnd)!=0 ) {
  			
  			final int exStyle = User32.INSTANCE.GetWindowLongW(hWnd, User32.GWL_EXSTYLE);
  			if ( (exStyle&User32.WS_EX_LAYERED)==0 ) {
  				User32.INSTANCE.SetWindowLongW(hWnd, User32.GWL_EXSTYLE, exStyle | User32.WS_EX_LAYERED);
  			}
  
  			// Create a DC source of the image
  			final Pointer clientDC= User32.INSTANCE.GetDC(hWnd);
  			final Pointer memDC = Gdi32.INSTANCE.CreateCompatibleDC(clientDC);
  			final Pointer oldBmp = Gdi32.INSTANCE.SelectObject(memDC, imageHandle );
  			
  			User32.INSTANCE.ReleaseDC(hWnd, clientDC);
  
  			// Destination Area
  			final RECT windowRect = new RECT();
  			User32.INSTANCE.GetWindowRect(hWnd, windowRect);
  
  			// Forward
  			final BLENDFUNCTION bf = new BLENDFUNCTION();
  			bf.BlendOp = BLENDFUNCTION.AC_SRC_OVER;
  			bf.BlendFlags = 0;
  			bf.SourceConstantAlpha = (byte)alpha; // Level set
  			bf.AlphaFormat = BLENDFUNCTION.AC_SRC_ALPHA;
  
  			final POINT lt = new POINT();
  			lt.x = windowRect.left;
  			lt.y = windowRect.top;
  			final SIZE size = new SIZE();
  			size.cx = windowRect.Width();
  			size.cy = windowRect.Height();
  			final POINT zero = new POINT();
  			User32.INSTANCE.UpdateLayeredWindow( 
  					hWnd, Pointer.NULL, 
  					lt, size,
  					memDC, zero, 0, bf, User32.ULW_ALPHA );
  
  			// Replace the bitmap you
  			Gdi32.INSTANCE.SelectObject(memDC, oldBmp);
  
              // Bring to front
              if( alwaysOnTop )
              {
                  User32.INSTANCE.BringWindowToTop( hWnd );
              }
              
  			Gdi32.INSTANCE.DeleteDC(memDC);
  		}
  	}
  
  	/**
  	 * Image to display.
  	 */
  	private WindowsNativeImage image;
  
  	/**
  	 * The concentration shown. 0 = not at all, 255 = full display.
  	 */
  	private int alpha = 255;
  
  	@Override
  	public String toString() {
  		return "LayeredWindow[hashCode="+hashCode()+",bounds="+getBounds()+"]";
  	}
  	
  	@Override
  	public void paint(final Graphics g) {
  		if (getImage() != null) {
  			// JNI with drawing images using the a value.
  			paint(getImage().getHandle(), getAlpha());
  		}
  	}
  
  	private WindowsNativeImage getImage() {
  		return this.image;
  	}
  
  	public void setImage(final NativeImage image) {
  		this.image = (WindowsNativeImage)image;
  	}
  
  	public int getAlpha() {
  		return this.alpha;
  	}
  
  	public void setAlpha(final int alpha) {
  		this.alpha = alpha;
  	}
  
      @Override
  	public void updateImage() {
  		repaint();
  	}
      
      @Override
      public void setStayOnTop( boolean newAlwaysOnTop )
      {
          alwaysOnTop = newAlwaysOnTop;
      }
  }