/*
 * 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.core.ext.typeinfo.NotFoundException;
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.CssProperty.DotPathValue;
import com.google.gwt.resources.css.ast.CssProperty.ExpressionValue;
import com.google.gwt.resources.css.ast.CssProperty.IdentValue;
import com.google.gwt.resources.css.ast.CssRule;
import com.google.gwt.resources.css.ast.CssSprite;
import com.google.gwt.resources.ext.ResourceContext;
import com.google.gwt.resources.ext.ResourceGeneratorUtil;

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();
    DotPathValue 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");
    }

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

    // Find the image accessor method
    JMethod imageMethod;
    try {
      imageMethod = ResourceGeneratorUtil.getMethodByPath(bundleType,
          functionName.getParts(), imageResourceType);
    } catch (NotFoundException e) {
      logger.log(TreeLogger.ERROR, "Unable to find ImageResource method "
          + functionName + " in " + bundleType.getQualifiedSourceName() + " : "
          + e.getMessage());
      throw new CssCompilerException("Cannot find image function");
    }

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

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

    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
        + ".getSafeUri().asString() + \"\\\") -\" + " + 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);
  }
}
