/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.myfaces.tobago.internal.renderkit.renderer;

import org.apache.myfaces.tobago.internal.component.AbstractUIStyle;
import org.apache.myfaces.tobago.internal.context.Nonce;
import org.apache.myfaces.tobago.internal.util.StringUtils;
import org.apache.myfaces.tobago.internal.util.StyleRenderUtils;
import org.apache.myfaces.tobago.layout.Display;
import org.apache.myfaces.tobago.layout.GridSpan;
import org.apache.myfaces.tobago.layout.Measure;
import org.apache.myfaces.tobago.layout.Overflow;
import org.apache.myfaces.tobago.layout.Position;
import org.apache.myfaces.tobago.layout.TextAlign;
import org.apache.myfaces.tobago.renderkit.RendererBase;
import org.apache.myfaces.tobago.renderkit.css.Styles;
import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import java.io.IOException;

public class StyleRenderer extends RendererBase {

  @Override
  public void encodeBegin(final FacesContext facesContext, final UIComponent component) throws IOException {

    final AbstractUIStyle style = (AbstractUIStyle) component;
    final TobagoResponseWriter writer = getResponseWriter(facesContext);

    final String file = style.getFile();
    if (StringUtils.isNotBlank(file)) {

      writer.startElement(HtmlElements.LINK);
      writer.writeAttribute(HtmlAttributes.REL, "stylesheet", false);
      writer.writeAttribute(HtmlAttributes.HREF, file, true);
//    writer.writeAttribute(HtmlAttributes.MEDIA, "screen", false);
      writer.writeAttribute(HtmlAttributes.TYPE, "text/css", false);
      writer.endElement(HtmlElements.LINK);

/* tbd: check, if this
      writer.startElement(HtmlElements.STYLE);
      writer.writeAttribute(HtmlAttributes.TYPE, "text/css", false);
      writer.writeAttribute(HtmlAttributes.NONCE, Nonce.getNonce(facesContext), false);
//    writer.writeAttribute(HtmlAttributes.MEDIA, "screen", false);
      writer.writeText("@import url(");
      writer.writeText(file);
      writer.writeText(");");
      writer.endElement(HtmlElements.STYLE);
*/

    } else {

      final Measure width = style.getWidth();
      final Measure height = style.getHeight();
      final Measure minWidth = style.getMinWidth();
      final Measure minHeight = style.getMinHeight();
      final Measure maxWidth = style.getMaxWidth();
      final Measure maxHeight = style.getMaxHeight();
      final Measure left = style.getLeft();
      final Measure right = style.getRight();
      final Measure top = style.getTop();
      final Measure bottom = style.getBottom();
      final Measure paddingLeft = style.getPaddingLeft();
      final Measure paddingRight = style.getPaddingRight();
      final Measure paddingTop = style.getPaddingTop();
      final Measure paddingBottom = style.getPaddingBottom();
      final Measure marginLeft = style.getMarginLeft();
      final Measure marginRight = style.getMarginRight();
      final Measure marginTop = style.getMarginTop();
      final Measure marginBottom = style.getMarginBottom();
      final Overflow overflowX = style.getOverflowX();
      final Overflow overflowY = style.getOverflowY();
      final Display display = style.getDisplay();
      final Position position = style.getPosition();
      final TextAlign textAlign = style.getTextAlign();
      final String backgroundImage = style.getBackgroundImage();
      final Number flexGrow = style.getFlexGrow();
      final Number flexShrink = style.getFlexShrink();
      final Measure flexBasis = style.getFlexBasis();
      final String gridTemplateColumns = style.getGridTemplateColumns();
      final String gridTemplateRows = style.getGridTemplateRows();
      final GridSpan gridColumn = style.getGridColumn();
      final GridSpan gridRow = style.getGridRow();

      // todo: backgroundPosition and zIndex

      if (width != null
          || height != null
          || minWidth != null
          || minHeight != null
          || maxWidth != null
          || maxHeight != null
          || left != null
          || right != null
          || top != null
          || bottom != null
          || paddingLeft != null
          || paddingRight != null
          || paddingTop != null
          || paddingBottom != null
          || marginLeft != null
          || marginRight != null
          || marginTop != null
          || marginBottom != null
          || overflowX != null
          || overflowY != null
          || display != null
          || position != null
          || textAlign != null
          || backgroundImage != null
          || flexGrow != null
          || flexShrink != null
          || flexBasis != null
          || gridTemplateColumns != null
          || gridTemplateRows != null
          || gridColumn != null
          || gridRow != null) {

        writer.startElement(HtmlElements.STYLE);
        writer.writeAttribute(HtmlAttributes.NONCE, Nonce.getNonce(facesContext), false);
        writer.writeIdAttribute(style.getClientId(facesContext));
        final String selector = style.getSelector();
        if (selector != null) {
          StyleRenderUtils.writeSelector(writer, selector);
        } else {
          final String parentId = style.getParent().getClientId(facesContext);
          StyleRenderUtils.writeIdSelector(writer, parentId);
        }
        writer.writeText("{");
        if (width != null) {
          encodeStyle(writer, Styles.width, width.serialize());
        }
        if (height != null) {
          encodeStyle(writer, Styles.height, height.serialize());
        }
        if (minWidth != null) {
          encodeStyle(writer, Styles.minWidth, minWidth.serialize());
        }
        if (minHeight != null) {
          encodeStyle(writer, Styles.minHeight, minHeight.serialize());
        }
        if (maxWidth != null) {
          encodeStyle(writer, Styles.maxWidth, maxWidth.serialize());
        }
        if (maxHeight != null) {
          encodeStyle(writer, Styles.maxHeight, maxHeight.serialize());
        }
        if (left != null) {
          encodeStyle(writer, Styles.left, left.serialize());
        }
        if (right != null) {
          encodeStyle(writer, Styles.right, right.serialize());
        }
        if (top != null) {
          encodeStyle(writer, Styles.top, top.serialize());
        }
        if (bottom != null) {
          encodeStyle(writer, Styles.bottom, bottom.serialize());
        }
        if (paddingLeft != null) {
          encodeStyle(writer, Styles.paddingLeft, paddingLeft.serialize());
        }
        if (paddingRight != null) {
          encodeStyle(writer, Styles.paddingRight, paddingRight.serialize());
        }
        if (paddingTop != null) {
          encodeStyle(writer, Styles.paddingTop, paddingTop.serialize());
        }
        if (paddingBottom != null) {
          encodeStyle(writer, Styles.paddingBottom, paddingBottom.serialize());
        }
        if (marginLeft != null) {
          encodeStyle(writer, Styles.marginLeft, marginLeft.serialize());
        }
        if (marginRight != null) {
          encodeStyle(writer, Styles.marginRight, marginRight.serialize());
        }
        if (marginTop != null) {
          encodeStyle(writer, Styles.marginTop, marginTop.serialize());
        }
        if (marginBottom != null) {
          encodeStyle(writer, Styles.marginBottom, marginBottom.serialize());
        }
        if (overflowX != null) {
          encodeStyle(writer, Styles.overflowX, overflowX.name());
        }
        if (overflowY != null) {
          encodeStyle(writer, Styles.overflowY, overflowY.name());
        }
        if (display != null) {
          encodeStyle(writer, Styles.display, display.encode());
        }
        if (position != null) {
          encodeStyle(writer, Styles.position, position.name());
        }
        if (textAlign != null) {
          encodeStyle(writer, Styles.textAlign, textAlign.name());
        }
        if (backgroundImage != null) {
          encodeStyle(writer, Styles.backgroundImage, backgroundImage);
        }
        if (flexGrow != null) {
          encodeStyle(writer, Styles.flexGrow, String.valueOf(flexGrow));
        }
        if (flexShrink != null) {
          encodeStyle(writer, Styles.flexShrink, String.valueOf(flexShrink));
        }
        if (flexBasis != null) {
          encodeStyle(writer, Styles.flexBasis, flexBasis.serialize());
        }
        if (gridTemplateColumns != null) {
          encodeStyle(writer, Styles.gridTemplateColumns, gridTemplateColumns);
          encodeStyle(writer, "-ms-grid-columns", gridTemplateColumns);
        }
        if (gridTemplateRows != null) {
          encodeStyle(writer, Styles.gridTemplateRows, gridTemplateRows);
          encodeStyle(writer, "-ms-grid-rows", gridTemplateRows);
        }
        if (gridColumn != null) {
          encodeStyle(writer, Styles.gridColumn, gridColumn.encode());
          encodeStyle(writer, "-ms-grid-column", gridColumn.getStart());
          encodeStyle(writer, "-ms-grid-column-span", gridColumn.getSpan());
        }
        if (gridRow != null) {
          encodeStyle(writer, Styles.gridRow, gridRow.encode());
          encodeStyle(writer, "-ms-grid-row", gridRow.getStart());
          encodeStyle(writer, "-ms-grid-row-span", gridRow.getSpan());
        }
        writer.writeText("}");

        writer.endElement(HtmlElements.STYLE);
      }
    }
  }

  private void encodeStyle(
      final TobagoResponseWriter writer, final Styles name, final String value) throws IOException {
    writer.writeText(name.getCssName());
    writer.writeText(":");
    switch (name) {
      case backgroundImage:
        writer.writeText("url(");
        writer.write("'");
        writer.writeText(value);
        writer.write("'");
        writer.writeText(")");
        break;
      default:
        writer.writeText(value);

    }
    writer.writeText(";");
  }

// XXX remove me
  private void encodeStyle(final TobagoResponseWriter writer, final String name, final String value)
      throws IOException {
    writer.writeText(name);
    writer.writeText(":");
    writer.writeText(value);
    writer.writeText(";");
  }

// XXX remove me
  private void encodeStyle(final TobagoResponseWriter writer, final String name, final Integer value)
      throws IOException {
    if (value != null) {
      writer.writeText(name);
      writer.writeText(":");
      writer.writeText(value.toString());
      writer.writeText(";");
    }
  }
}
