/*******************************************************************************
 * Copyright (c) 2003, 2008 IBM Corporation and Others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Junji MAEDA - initial API and implementation
 *    Daisuke SATO - initial API and implementation
 *******************************************************************************/
package org.eclipse.actf.visualization.engines.lowvision.operator;

import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;

import org.eclipse.actf.visualization.engines.lowvision.LowVisionType;

public class BlurOp implements ILowVisionOperator {
	private ConvolveOp cop = null;

	public BlurOp(LowVisionType _lvType) {
		double pixel = _lvType.getEyesightPixel();

		int cPixel = (int) (Math.ceil(pixel));
		int fPixel = (int) (Math.floor(pixel));

		// ---square---

		int arrayWidth = 2 * (cPixel) + 1;
		double[][] blurArray = new double[arrayWidth][arrayWidth];
		if (cPixel == fPixel) {
			double area = (double) (arrayWidth * arrayWidth);
			for (int j = 0; j < arrayWidth; j++) {
				for (int i = 0; i < arrayWidth; i++) {
					blurArray[j][i] = 1.0 / area;
				}
			}
		} else if (cPixel == fPixel + 1) {
			double dicimal = pixel - fPixel;
			double area = (double) ((2.0 * pixel + 1.0) * (2.0 * pixel + 1.0));

			double centerValue = 1.0 / area;
			for (int j = 1; j < arrayWidth - 1; j++) {
				for (int i = 1; i < arrayWidth - 1; i++) {
					blurArray[j][i] = centerValue;
				}
			}

			double edgeValue = dicimal / area;
			for (int j = 1; j < arrayWidth - 1; j++) {
				blurArray[j][0] = edgeValue;
				blurArray[j][arrayWidth - 1] = edgeValue;
				blurArray[0][j] = edgeValue;
				blurArray[arrayWidth - 1][j] = edgeValue;
			}

			double cornerValue = dicimal * dicimal / area;
			blurArray[0][0] = cornerValue;
			blurArray[0][arrayWidth - 1] = cornerValue;
			blurArray[arrayWidth - 1][0] = cornerValue;
			blurArray[arrayWidth - 1][arrayWidth - 1] = cornerValue;

			// ---square---

			// use octagon
			double temp = blurArray[0][0] * 4;
			double cornerHalf = 0;// blurArray[0][0] / 2.0;
			blurArray[0][0] = cornerHalf;
			blurArray[0][arrayWidth - 1] = cornerHalf;
			blurArray[arrayWidth - 1][0] = cornerHalf;
			blurArray[arrayWidth - 1][arrayWidth - 1] = cornerHalf;
			blurArray[arrayWidth / 2][arrayWidth / 2] += temp;
			// (cornerHalf * 4.0);
		} else {
			// assert
		}

		float[] element = new float[arrayWidth * arrayWidth];
		int k = 0;
		for (int j = 0; j < arrayWidth; j++) {
			for (int i = 0; i < arrayWidth; i++) {
				element[k] = (float) (blurArray[j][i]);
				k++;
			}
		}
		Kernel kernel = new Kernel(arrayWidth, arrayWidth, element);
		cop = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);

	}

	public BufferedImage filter(BufferedImage _src, BufferedImage _dest) {
		return newFilter(_src, _dest); // by daisuke
		// return (cop.filter(_src, _dest)); // by maeda
	}

	private BufferedImage newFilter(BufferedImage _src, BufferedImage _dest) {
		if (_dest == null) {
			_dest = new BufferedImage(_src.getWidth(), _src.getHeight(), _src
					.getType());
		}

		Kernel karnel = cop.getKernel();
		int w = karnel.getWidth();
		int h = karnel.getHeight();
		float[] d = new float[w * h];
		karnel.getKernelData(d);

		int width = _src.getWidth();
		int height = _src.getHeight();

		double N = 1.005;

		double[] pow = new double[256];
		for (int i = 0; i < pow.length; i++) {
			pow[i] = Math.pow(N, i);
		}
		double logN = Math.log(N);

		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				double dr = 0, dg = 0, db = 0;

				for (int xx = 0; xx < w; xx++) {
					for (int yy = 0; yy < h; yy++) {
						int xxx = x + xx - w / 2;
						int yyy = y + yy - h / 2;
						xxx = xxx > 0 ? xxx : 0;
						xxx = xxx >= width ? width - 1 : xxx;
						yyy = yyy > 0 ? yyy : 0;
						yyy = yyy >= height ? height - 1 : yyy;

						int rgb = _src.getRGB(xxx, yyy);
						int ir = (rgb & 0xFF0000) >> 16;
						int ig = (rgb & 0x00FF00) >> 8;
						int ib = (rgb & 0x0000FF);

						dr += pow[ir] * d[xx * w + yy];
						dg += pow[ig] * d[xx * w + yy];
						db += pow[ib] * d[xx * w + yy];
					}
				}
				int ir = (int) (Math.log(dr) / logN);
				int ig = (int) (Math.log(dg) / logN);
				int ib = (int) (Math.log(db) / logN);

				ir = ir > 255 ? 255 : ir;
				ig = ig > 255 ? 255 : ig;
				ib = ib > 255 ? 255 : ib;

				_dest.setRGB(x, y, (ir << 16) + (ig << 8) + ib);
			}
		}

		return _dest;
	}

	public WritableRaster filter(Raster _src, WritableRaster _dest) {
		return (cop.filter(_src, _dest));
	}
}
