/*
 * Copyright 2009 Google Inc.
 * 
 * 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.google.gwt.resources.css;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.resources.client.ImageResource.ImageOptions;
import com.google.gwt.resources.client.ImageResource.RepeatStyle;
import com.google.gwt.resources.css.ast.Context;
import com.google.gwt.resources.css.ast.CssCompilerException;
import com.google.gwt.resources.css.ast.CssModVisitor;
import com.google.gwt.resources.css.ast.CssProperty;
import com.google.gwt.resources.css.ast.CssRule;
import com.google.gwt.resources.css.ast.CssSprite;
import com.google.gwt.resources.css.ast.CssProperty.ExpressionValue;
import com.google.gwt.resources.css.ast.CssProperty.IdentValue;
import com.google.gwt.resources.ext.ResourceContext;

import java.util.List;

/**
 * Replaces CssSprite nodes with CssRule nodes that will display the sprited
 * image. The real trick with spriting the images is to reuse the ImageResource
 * processing framework by requiring the sprite to be defined in terms of an
 * ImageResource.
 */
public class Spriter extends CssModVisitor {
  private final ResourceContext context;
  private final TreeLogger logger;

  public Spriter(TreeLogger logger, ResourceContext context) {
    this.logger = logger.branch(TreeLogger.DEBUG,
        "Creating image sprite classes");
    this.context = context;
  }

  @Override
  public void endVisit(CssSprite x, Context ctx) {
    JClassType bundleType = context.getClientBundleType();
    String functionName = x.getResourceFunction();

    if (functionName == null) {
      logger.log(TreeLogger.ERROR, "The @sprite rule " + x.getSelectors()
          + " must specify the " + CssSprite.IMAGE_PROPERTY_NAME + " property");
      throw new CssCompilerException("No image property specified");
    }

    // Find the image accessor method
    JMethod imageMethod = null;
    JMethod[] allMethods = bundleType.getOverridableMethods();
    for (int i = 0; imageMethod == null && i < allMethods.length; i++) {
      JMethod candidate = allMethods[i];
      // If the function name matches and takes no parameters
      if (candidate.getName().equals(functionName)
          && candidate.getParameters().length == 0) {
        // We have a match
        imageMethod = candidate;
      }
    }

    // Method unable to be located
    if (imageMethod == null) {
      logger.log(TreeLogger.ERROR, "Unable to find ImageResource method "
          + functionName + " in " + bundleType.getQualifiedSourceName());
      throw new CssCompilerException("Cannot find image function");
    }

    JClassType imageResourceType = context.getGeneratorContext().getTypeOracle().findType(
        ImageResource.class.getName());
    assert imageResourceType != null;

    if (!imageResourceType.isAssignableFrom(imageMethod.getReturnType().isClassOrInterface())) {
      logger.log(TreeLogger.ERROR, "The return type of " + functionName
          + " is not assignable to " + imageResourceType.getSimpleSourceName());
      throw new CssCompilerException("Incorrect return type for "
          + CssSprite.IMAGE_PROPERTY_NAME + " method");
    }

    ImageOptions options = imageMethod.getAnnotation(ImageOptions.class);
    RepeatStyle repeatStyle;
    if (options != null) {
      repeatStyle = options.repeatStyle();
    } else {
      repeatStyle = RepeatStyle.None;
    }

    String instance = "(" + context.getImplementationSimpleSourceName()
        + ".this." + functionName + "())";

    CssRule replacement = new CssRule();
    replacement.getSelectors().addAll(x.getSelectors());
    List<CssProperty> properties = replacement.getProperties();

    if (repeatStyle == RepeatStyle.None
        || repeatStyle == RepeatStyle.Horizontal) {
      properties.add(new CssProperty("height", new ExpressionValue(instance
          + ".getHeight() + \"px\""), false));
    }

    if (repeatStyle == RepeatStyle.None || repeatStyle == RepeatStyle.Vertical) {
      properties.add(new CssProperty("width", new ExpressionValue(instance
          + ".getWidth() + \"px\""), false));
    }
    properties.add(new CssProperty("overflow", new IdentValue("hidden"), false));

    String repeatText;
    switch (repeatStyle) {
      case None:
        repeatText = " no-repeat";
        break;
      case Horizontal:
        repeatText = " repeat-x";
        break;
      case Vertical:
        repeatText = " repeat-y";
        break;
      case Both:
        repeatText = " repeat";
        break;
      default:
        throw new RuntimeException("Unknown repeatStyle " + repeatStyle);
    }

    String backgroundExpression = "\"url(\\\"\" + " + instance
        + ".getURL() + \"\\\") -\" + " + instance + ".getLeft() + \"px -\" + "
        + instance + ".getTop() + \"px " + repeatText + "\"";
    properties.add(new CssProperty("background", new ExpressionValue(
        backgroundExpression), false));

    // Retain any user-specified properties
    properties.addAll(x.getProperties());

    ctx.replaceMe(replacement);
  }
}
