/*
 * 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.AbstractUIStars;
import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
import org.apache.myfaces.tobago.util.ComponentUtils;
import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;

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

public class StarsRenderer extends MessageLayoutRendererBase {

  @Override
  protected void encodeBeginField(FacesContext facesContext, UIComponent component) throws IOException {

    final TobagoResponseWriter writer = getResponseWriter(facesContext);
    final AbstractUIStars stars = (AbstractUIStars) component;
    final String clientId = stars.getClientId(facesContext);
    final String fieldId = stars.getFieldId(facesContext);
    final String hiddenInputId = clientId + ComponentUtils.SUB_SEPARATOR + "input";
    final String sliderId = clientId + ComponentUtils.SUB_SEPARATOR + "slider";
    final int value = stars.getRangeValue();
    final int max = stars.getRangeMax();
    final Double placeholder = stars.getPlaceholder();
    final boolean readonly = stars.isReadonly();
    final boolean disabled = stars.isDisabled();
    final boolean required = stars.isRequired();
    final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, stars);

    final String sliderValue = stars.getSubmittedValue() != null
        ? (String) stars.getSubmittedValue() : String.valueOf(value);
    final String hiddenInputValue = required && "0".equals(sliderValue) ? null : sliderValue;

    writer.startElement(HtmlElements.TOBAGO_STARS);
    writer.writeIdAttribute(fieldId);
    writer.writeClassAttribute(
        TobagoClass.STARS,
        TobagoClass.STARS.createMarkup(stars.getMarkup()),
        stars.getCustomClass());

    // The hidden input must be used to submit the rating. The 'required' attribute is not allowed on slider component.
    writer.startElement(HtmlElements.INPUT);
    writer.writeIdAttribute(hiddenInputId);
    writer.writeNameAttribute(clientId);
    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN);
    writer.writeAttribute(HtmlAttributes.VALUE, hiddenInputValue, true);
    writer.writeAttribute(HtmlAttributes.READONLY, readonly);
    writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
    writer.writeAttribute(HtmlAttributes.REQUIRED, required);
    writer.endElement(HtmlElements.INPUT);

    writer.startElement(HtmlElements.SPAN);
    writer.writeClassAttribute(TobagoClass.STARS__CONTAINER);

    writer.startElement(HtmlElements.INPUT);
    writer.writeIdAttribute(sliderId);
    writer.writeNameAttribute(clientId);
    writer.writeClassAttribute(TobagoClass.STARS__SLIDER);
    writer.writeAttribute(HtmlAttributes.TYPE, readonly || disabled ? HtmlInputTypes.HIDDEN : HtmlInputTypes.RANGE);
    writer.writeAttribute(HtmlAttributes.MIN, required ? 1 : 0);
    writer.writeAttribute(HtmlAttributes.MAX, max);
    writer.writeAttribute(HtmlAttributes.VALUE, sliderValue, true);
    if (placeholder != null) {
      writer.writeAttribute(HtmlAttributes.PLACEHOLDER, placeholder.toString(), true);
    }
    writer.writeAttribute(HtmlAttributes.READONLY, readonly);
    writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
    writer.writeAttribute(HtmlAttributes.REQUIRED, required);
    HtmlRendererUtils.renderFocus(clientId, stars.isFocus(), ComponentUtils.isError(stars), facesContext, writer);
    writer.writeAttribute(HtmlAttributes.TABINDEX, stars.getTabIndex());
    writer.writeAttribute(HtmlAttributes.TITLE, title, true);
    writer.endElement(HtmlElements.INPUT);

    encodeBehavior(writer, facesContext, stars);

    writer.startElement(HtmlElements.DIV);
    writer.writeClassAttribute(TobagoClass.STARS__FOCUS_BOX);
    writer.endElement(HtmlElements.DIV);
    writer.startElement(HtmlElements.SPAN);
    writer.writeClassAttribute(TobagoClass.STARS__TOOLTIP, BootstrapClass.FADE);
    writer.endElement(HtmlElements.SPAN);
    writer.startElement(HtmlElements.SPAN);
    writer.writeClassAttribute(TobagoClass.STARS__SELECTED);
    writer.endElement(HtmlElements.SPAN);
    writer.startElement(HtmlElements.SPAN);
    writer.writeClassAttribute(TobagoClass.STARS__UNSELECTED);
    writer.endElement(HtmlElements.SPAN);
    writer.startElement(HtmlElements.SPAN);
    writer.writeClassAttribute(TobagoClass.STARS__PRESELECTED);
    writer.endElement(HtmlElements.SPAN);

    writer.endElement(HtmlElements.SPAN);
  }

  @Override
  protected void encodeEndField(FacesContext facesContext, UIComponent component) throws IOException {
    final TobagoResponseWriter writer = getResponseWriter(facesContext);
    writer.endElement(HtmlElements.TOBAGO_STARS);
  }

  @Override
  protected String getFieldId(FacesContext facesContext, UIComponent component) {
    final AbstractUIStars stars = (AbstractUIStars) component;
    return stars.getFieldId(facesContext);
  }
}
