/*
 * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.awt;

import sun.awt.CustomCursor;
import java.awt.*;
import java.awt.image.*;
import sun.awt.image.ImageRepresentation;

/**
 * A class to encapsulate a custom image-based cursor.
 *
 * @see Component#setCursor
 * @author      Thomas Ball
 */
public abstract class X11CustomCursor extends CustomCursor {

    public X11CustomCursor(Image cursor, Point hotSpot, String name)
            throws IndexOutOfBoundsException {
        super(cursor, hotSpot, name);
    }

    protected void createNativeCursor(Image im, int[] pixels, int width, int height,
                                      int xHotSpot, int yHotSpot) {

        class CCount implements Comparable {
            int color;
            int count;

            public CCount(int cl, int ct) {
                color = cl;
                count = ct;
            }

            public int compareTo(Object cc) {
                return ((CCount)cc).count - count;
            }
        }

        int tmp[] = new int[pixels.length];
        for (int i=0; i<pixels.length; i++) {
            if ((pixels[i] & 0xff000000) == 0) {
                tmp[i] = -1;
            } else {
                tmp[i] = pixels[i] & 0x00ffffff;
            }
        }
        java.util.Arrays.sort(tmp);

        int fc = 0x000000;
        int bc = 0xffffff;
        CCount cols[] = new CCount[pixels.length];

        int is = 0;
        int numColors = 0;
        while ( is < pixels.length ) {
            if (tmp[is] != -1) {
                cols[numColors++] = new CCount(tmp[is], 1);
                break;
            }
            is ++;
        }

        for (int i = is+1; i < pixels.length; i++) {
            if (tmp[i] != cols[numColors-1].color) {
                cols[numColors++] = new CCount(tmp[i], 1);
            } else {
                cols[numColors-1].count ++;
            }
        }
        java.util.Arrays.sort(cols, 0, numColors);

        if (numColors > 0) fc = cols[0].color;
        int fcr = (fc >> 16) & 0x000000ff;
        int fcg = (fc >>  8) & 0x000000ff;
        int fcb = (fc >>  0) & 0x000000ff;

        int rdis = 0;
        int gdis = 0;
        int bdis = 0;
        for (int j = 1; j < numColors; j++) {
            int rr = (cols[j].color >> 16) & 0x000000ff;
            int gg = (cols[j].color >>  8) & 0x000000ff;
            int bb = (cols[j].color >>  0) & 0x000000ff;
            rdis = rdis + cols[j].count * rr;
            gdis = gdis + cols[j].count * gg;
            bdis = bdis + cols[j].count * bb;
        }
        int rest = pixels.length - ((numColors > 0) ? cols[0].count : 0);
    // 4653170 Avoid divide / zero exception
    if (rest > 0) {
        rdis = rdis / rest - fcr;
        gdis = gdis / rest - fcg;
        bdis = bdis / rest - fcb;
    }
        rdis = (rdis*rdis + gdis*gdis + bdis*bdis) / 2;
        // System.out.println(" rdis is "+ rdis);

        for (int j = 1; j < numColors; j++) {
            int rr = (cols[j].color >> 16) & 0x000000ff;
            int gg = (cols[j].color >>  8) & 0x000000ff;
            int bb = (cols[j].color >>  0) & 0x000000ff;

            if ( (rr-fcr)*(rr-fcr) + (gg-fcg)*(gg-fcg) + (bb-fcb)*(bb-fcb)
                 >= rdis )  {
                bc = cols[j].color;
                break;
            }
        }
        int bcr = (bc >> 16) & 0x000000ff;
        int bcg = (bc >>  8) & 0x000000ff;
        int bcb = (bc >>  0) & 0x000000ff;


        // On Solaris 2.5.x, the above code for cursor of any size runs fine
        // but on Solaris 2.6, the width of a cursor has to be 8 divisible,
        //   otherwise, the cursor could be displayed as garbaged.
        // To work around the 2.6 problem, the following code pads any cursor
        //   with a transparent area to make a new cursor of width 8 multiples.
        // --- Bug 4148455
        int wNByte = (width + 7)/8;
        int tNByte = wNByte * height;
        byte[] xorMask = new byte[tNByte];
        byte[] andMask = new byte[tNByte];

        for (int i = 0; i < width; i++) {
            int omask = 1 << (i % 8);
            for (int j = 0; j < height; j++) {
                int ip = j*width + i;
                int ibyte = j*wNByte + i/8;

                if ((pixels[ip] & 0xff000000) != 0) {
                    andMask[ibyte] |= omask;
                }

                int pr = (pixels[ip] >> 16) & 0x000000ff;
                int pg = (pixels[ip] >>  8) & 0x000000ff;
                int pb = (pixels[ip] >>  0) & 0x000000ff;
                if ( (pr-fcr)*(pr-fcr) + (pg-fcg)*(pg-fcg) + (pb-fcb)*(pb-fcb)
                  <= (pr-bcr)*(pr-bcr) + (pg-bcg)*(pg-bcg) + (pb-bcb)*(pb-bcb) ) {
                    // show foreground color
                    xorMask[ibyte] |= omask;
                }
            }
        }

        createCursor(xorMask, andMask, 8*wNByte, height, fc, bc, xHotSpot, yHotSpot);
    }

    protected abstract void createCursor(byte[] xorMask, byte[] andMask,
                                     int width, int height,
                                     int fcolor, int bcolor,
                                     int xHotSpot, int yHotSpot);

}
