/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.ui;

import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.AppIconScheme;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.util.ui.UIUtil;
import org.apache.sanselan.ImageFormat;
import org.apache.sanselan.Sanselan;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

public abstract class AppIcon {

  private static final Logger LOG = Logger.getInstance("AppIcon");

  static AppIcon ourMacImpl;
  static AppIcon ourWin7Impl;
  static AppIcon ourEmptyImpl;

  public abstract boolean setProgress(Project project, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk);

  public abstract boolean hideProgress(Project project, Object processId);

  public abstract void setErrorBadge(Project project, String text);

  public abstract void setOkBadge(Project project, boolean visible);

  public abstract void requestAttention(Project project, boolean critical);

  public abstract void requestFocus(IdeFrame frame);

  public static AppIcon getInstance() {
    if (ourMacImpl == null) {
      ourMacImpl = new MacAppIcon();
      ourWin7Impl = new Win7AppIcon();
      ourEmptyImpl = new EmptyIcon();
    }

    if (SystemInfo.isMac && SystemInfo.isJavaVersionAtLeast("1.6")) {
      return ourMacImpl;
    }
    else if (SystemInfo.isWin7OrNewer) {
      return ourWin7Impl;
    }
    else {
      return ourEmptyImpl;
    }
  }

  private static abstract class BaseIcon extends AppIcon {

    private ApplicationActivationListener myAppListener;
    protected Object myCurrentProcessId;
    protected double myLastValue;

    @Override
    public final boolean setProgress(Project project, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
      if (!isAppActive() && Registry.is("ide.appIcon.progress") && (myCurrentProcessId == null || myCurrentProcessId.equals(processId))) {
        return _setProgress(getIdeFrame(project), processId, scheme, value, isOk);
      }
      else {
        return false;
      }
    }

    @Override
    public final boolean hideProgress(Project project, Object processId) {
      if (Registry.is("ide.appIcon.progress")) {
        return _hideProgress(getIdeFrame(project), processId);
      }
      else {
        return false;
      }
    }

    @Override
    public final void setErrorBadge(Project project, String text) {
      if (!isAppActive() && Registry.is("ide.appIcon.badge")) {
        _setOkBadge(getIdeFrame(project), false);
        _setTextBadge(getIdeFrame(project), text);
      }
    }

    @Override
    public final void setOkBadge(Project project, boolean visible) {
      if (!isAppActive() && Registry.is("ide.appIcon.badge")) {
        _setTextBadge(getIdeFrame(project), null);
        _setOkBadge(getIdeFrame(project), visible);
      }
    }

    @Override
    public final void requestAttention(Project project, boolean critical) {
      if (!isAppActive() && Registry.is("ide.appIcon.requestAttention")) {
        _requestAttention(getIdeFrame(project), critical);
      }
    }

    public abstract boolean _setProgress(IdeFrame frame, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk);

    public abstract boolean _hideProgress(IdeFrame frame, Object processId);

    public abstract void _setTextBadge(IdeFrame frame, String text);

    public abstract void _setOkBadge(IdeFrame frame, boolean visible);

    public abstract void _requestAttention(IdeFrame frame, boolean critical);

    protected abstract IdeFrame getIdeFrame(Project project);

    private boolean isAppActive() {
      Application app = ApplicationManager.getApplication();

      if (app != null && myAppListener == null) {
        myAppListener = new ApplicationActivationListener.Adapter() {
          @Override
          public void applicationActivated(IdeFrame ideFrame) {
            hideProgress(ideFrame.getProject(), myCurrentProcessId);
            _setOkBadge(ideFrame, false);
            _setTextBadge(ideFrame, null);
          }
        };
        app.getMessageBus().connect().subscribe(ApplicationActivationListener.TOPIC, myAppListener);
      }

      return app != null && app.isActive();
    }
  }


  private static class MacAppIcon extends BaseIcon {

    private static BufferedImage myAppImage;

    private BufferedImage getAppImage() {
      assertIsDispatchThread();

      try {
        if (myAppImage != null) return myAppImage;

        Object app = getApp();
        Image appImage = (Image)getAppMethod("getDockIconImage").invoke(app);

        if (appImage == null) return null;

        int width = appImage.getWidth(null);
        int height = appImage.getHeight(null);
        BufferedImage img = UIUtil.createImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = img.createGraphics();
        g2d.drawImage(appImage, null, null);
        myAppImage = img;
      }
      catch (NoSuchMethodException e) {
        return null;
      }
      catch (Exception e) {
        LOG.error(e);
      }

      return myAppImage;
    }

    @Override
    public void _setTextBadge(IdeFrame frame, String text) {
      assertIsDispatchThread();

      try {
        getAppMethod("setDockIconBadge", String.class).invoke(getApp(), text);
      }
      catch (NoSuchMethodException e) {
        return;
      }
      catch (Exception e) {
        LOG.error(e);
      }
    }

    @Override
    public void requestFocus(IdeFrame frame) {
      assertIsDispatchThread();

      try {
        getAppMethod("requestForeground", boolean.class).invoke(getApp(), true);
      }
      catch (NoSuchMethodException e) {
        return;
      }
      catch (Exception e) {
        LOG.error(e);
      }
    }

    @Override
    public void _requestAttention(IdeFrame frame, boolean critical) {
      assertIsDispatchThread();

      try {
        getAppMethod("requestUserAttention", boolean.class).invoke(getApp(), critical);
      }
      catch (NoSuchMethodException e) {
        return;
      }
      catch (Exception e) {
        LOG.error(e);
      }
    }

    @Override
    protected IdeFrame getIdeFrame(Project project) {
      return null;
    }

    @Override
    public boolean _hideProgress(IdeFrame frame, Object processId) {
      assertIsDispatchThread();

      if (getAppImage() == null) return false;
      if (myCurrentProcessId != null && !myCurrentProcessId.equals(processId)) return false;

      setDockIcon(getAppImage());
      myCurrentProcessId = null;
      myLastValue = 0;

      return true;
    }

    @Override
    public void _setOkBadge(IdeFrame frame, boolean visible) {
      assertIsDispatchThread();

      if (getAppImage() == null) return;

      AppImage img = createAppImage();

      if (visible) {
        Icon okIcon = AllIcons.Mac.AppIconOk512;

        int x = img.myImg.getWidth() - okIcon.getIconWidth();
        int y = 0;

        okIcon.paintIcon(JOptionPane.getRootFrame(), img.myG2d, x, y);
      }

      setDockIcon(img.myImg);
    }

    @Override
    public boolean _setProgress(IdeFrame frame, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
      assertIsDispatchThread();

      if (getAppImage() == null) return false;

      myCurrentProcessId = processId;

      if (Math.abs(myLastValue - value) < 0.02d) return true;

      try {
        int progressHeight = (int)(myAppImage.getHeight() * 0.13);
        int xInset = (int)(myAppImage.getWidth() * 0.05);
        int yInset = (int)(myAppImage.getHeight() * 0.15);

        final int width = myAppImage.getWidth() - xInset * 2;
        final int y = myAppImage.getHeight() - progressHeight - yInset;
        Shape rect = new RoundRectangle2D.Double(xInset, y, width, progressHeight, progressHeight, progressHeight);
        Shape border =
          new RoundRectangle2D.Double(xInset - 1, y - 1, width + 2, progressHeight + 2, (progressHeight + 2), (progressHeight + 2));
        Shape progress = new RoundRectangle2D.Double(xInset + 1, y + 1, (width - 2) * value, progressHeight - 1, (progressHeight - 2),
                                                     (progressHeight - 1));
        AppImage appImg = createAppImage();

        final Color brighter = Color.GRAY.brighter().brighter();
        final Color backGround = new Color(brighter.getRed(), brighter.getGreen(), brighter.getBlue(), 85);
        appImg.myG2d.setColor(backGround);
        appImg.myG2d.fill(rect);
        final Color color = isOk ? scheme.getOkColor() : scheme.getErrorColor();
        final Paint paint = UIUtil.getGradientPaint(xInset + 1, y + 1, color.brighter(),
                                                      xInset + 1, y + progressHeight - 1, color.darker().darker());
        appImg.myG2d.setPaint(paint);
        appImg.myG2d.fill(progress);
        appImg.myG2d.setColor(Color.GRAY.darker().darker());
        appImg.myG2d.draw(rect);
        appImg.myG2d.draw(border);

        setDockIcon(appImg.myImg);

        myLastValue = value;
      }
      catch (Exception e) {
        LOG.error(e);
      }
      finally {
        myCurrentProcessId = null;
      }

      return true;
    }

    private AppImage createAppImage() {
      BufferedImage current = UIUtil.createImage(getAppImage().getWidth(), getAppImage().getHeight(), BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = current.createGraphics();
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g.drawImage(getAppImage(), null, null);
      return new AppImage(current, g);
    }

    private class AppImage {
      BufferedImage myImg;
      Graphics2D myG2d;

      AppImage(BufferedImage img, Graphics2D g2d) {
        myImg = img;
        myG2d = g2d;
      }
    }

    private void setDockIcon(BufferedImage image) {
      try {
        getAppMethod("setDockIconImage", Image.class).invoke(getApp(), image);
      }
      catch (Exception e) {
        LOG.error(e);
      }
    }

    private Method getAppMethod(final String name, Class... args) throws NoSuchMethodException, ClassNotFoundException {
      return getAppClass().getMethod(name, args);
    }

    private Object getApp() throws NoSuchMethodException, ClassNotFoundException, InvocationTargetException, IllegalAccessException {
      return getAppClass().getMethod("getApplication").invoke(null);
    }

    private Class<?> getAppClass() throws ClassNotFoundException {
      return Class.forName("com.apple.eawt.Application");
    }
  }

  private static class Win7AppIcon extends BaseIcon {
    @Override
    public boolean _setProgress(IdeFrame frame, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
      myCurrentProcessId = processId;

      if (Math.abs(myLastValue - value) < 0.02d) {
        return true;
      }

      try {
        if (isValid(frame)) {
          Win7TaskBar.setProgress(frame, value, isOk);
        }
      }
      catch (Throwable e) {
        LOG.error(e);
      }

      myLastValue = value;
      myCurrentProcessId = null;
      return true;
    }

    @Override
    public boolean _hideProgress(IdeFrame frame, Object processId) {
      if (myCurrentProcessId != null && !myCurrentProcessId.equals(processId)) {
        return false;
      }

      try {
        if (isValid(frame)) {
          Win7TaskBar.hideProgress(frame);
        }
      }
      catch (Throwable e) {
        LOG.error(e);
      }

      myCurrentProcessId = null;
      myLastValue = 0;
      return true;
    }

    private static final Color ERROR_COLOR = new Color(197, 54, 13);

    @Override
    public void _setTextBadge(IdeFrame frame, String text) {
      if (!isValid(frame)) {
        return;
      }

      Object icon = null;

      if (text != null) {
        try {
          int size = 55;
          BufferedImage image = UIUtil.createImage(size, size, BufferedImage.TYPE_INT_ARGB);
          Graphics2D g = image.createGraphics();

          int roundSize = 40;
          g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g.setPaint(ERROR_COLOR);
          g.fillRoundRect(size / 2 - roundSize / 2, size / 2 - roundSize / 2, roundSize, roundSize, size, size);

          g.setColor(Color.white);
          Font font = g.getFont();
          g.setFont(new Font(font.getName(), font.getStyle(), 22));
          FontMetrics fontMetrics = g.getFontMetrics();
          int width = fontMetrics.stringWidth(text);
          g.drawString(text, size / 2 - width / 2, size / 2 - fontMetrics.getHeight() / 2 + fontMetrics.getAscent());

          ByteArrayOutputStream bytes = new ByteArrayOutputStream();
          Sanselan.writeImage(image, bytes, ImageFormat.IMAGE_FORMAT_ICO, new HashMap());
          icon = Win7TaskBar.createIcon(bytes.toByteArray());
        }
        catch (Throwable e) {
          LOG.error(e);
        }
      }

      try {
        Win7TaskBar.setOverlayIcon(frame, icon, icon != null);
      }
      catch (Throwable e) {
        LOG.error(e);
      }
    }

    private static Object myOkIcon;

    @Override
    public void _setOkBadge(IdeFrame frame, boolean visible) {
      if (!isValid(frame)) {
        return;
      }

      Object icon = null;

      if (visible) {
        synchronized (Win7AppIcon.class) {
          if (myOkIcon == null) {
            try {
              BufferedImage image = ImageIO.read(getClass().getResource("/mac/appIconOk512.png"));
              ByteArrayOutputStream bytes = new ByteArrayOutputStream();
              Sanselan.writeImage(image, bytes, ImageFormat.IMAGE_FORMAT_ICO, new HashMap());
              myOkIcon = Win7TaskBar.createIcon(bytes.toByteArray());
            }
            catch (Throwable e) {
              LOG.error(e);
              myOkIcon = null;
            }
          }

          icon = myOkIcon;
        }
      }

      try {
        Win7TaskBar.setOverlayIcon(frame, icon, false);
      }
      catch (Throwable e) {
        LOG.error(e);
      }
    }

    @Override
    public void _requestAttention(IdeFrame frame, boolean critical) {
      try {
        if (isValid(frame)) {
          Win7TaskBar.attention(frame, critical);
        }
      }
      catch (Throwable e) {
        LOG.error(e);
      }
    }

    @Override
    protected IdeFrame getIdeFrame(Project project) {
      return WindowManager.getInstance().getIdeFrame(project);
    }

    @Override
    public void requestFocus(IdeFrame frame) {
    }

    private static boolean isValid(IdeFrame frame) {
      return frame != null && ((Component)frame).isDisplayable();
    }
  }

  private static class EmptyIcon extends AppIcon {
    @Override
    public boolean setProgress(Project project, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
      return false;
    }

    @Override
    public boolean hideProgress(Project project, Object processId) {
      return false;
    }

    @Override
    public void setErrorBadge(Project project, String text) {
    }

    @Override
    public void setOkBadge(Project project, boolean visible) {
    }

    @Override
    public void requestAttention(Project project, boolean critical) {
    }

    @Override
    public void requestFocus(IdeFrame frame) {
    }
  }

  private static void assertIsDispatchThread() {
    Application app = ApplicationManager.getApplication();
    if (app != null) {
      if (!app.isUnitTestMode()) {
        app.assertIsDispatchThread();
      }
    }
    else {
      assert EventQueue.isDispatchThread();
    }
  }
}
