/*
 * 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.html5.renderkit.media;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.component.behavior.ClientBehavior;
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

import org.apache.myfaces.commons.util.DebugUtils;
import org.apache.myfaces.html5.component.media.AbstractMedia;
import org.apache.myfaces.html5.model.MediaInfo;
import org.apache.myfaces.html5.renderkit.util.HTML5;
import org.apache.myfaces.html5.renderkit.util.Html5RendererUtils;
import org.apache.myfaces.html5.renderkit.util.RendererUtils;

/**
 * Abstract base for media renderers.
 * 
 * @author Ali Ok
 * 
 */
public abstract class AbstractMediaRenderer extends Renderer
{
    private static final Logger log = Logger.getLogger(AbstractMediaRenderer.class.getName());

    protected static final String FACET_FALLBACK = "fallback";

    @Override
    public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
    {
        if (log.isLoggable(Level.FINE))
            log.fine("encodeBegin");

        super.encodeBegin(facesContext, uiComponent);

        RendererUtils.checkParamValidity(facesContext, uiComponent, AbstractMedia.class);

        ResponseWriter writer = facesContext.getResponseWriter();

        AbstractMedia component = (AbstractMedia) uiComponent;

        writer.startElement(getHtmlElementName(), uiComponent);

        // write id
        writer.writeAttribute(HTML5.ID_ATTR, component.getClientId(facesContext), null);

        // get the value and render the src attr
        String src = RendererUtils.getStringValue(facesContext, component);
        if (log.isLoggable(Level.FINE))
            log.fine("writing src '" + src + "'");
        if (src != null && src.length() > 0)
            writer.writeAttribute(HTML5.SRC_ATTR, src, "value");

        // no need to check the value of preload, it is bypassed anyway.
        // _checkPreload(component);

        renderPassThruAttrsAndEvents(facesContext, uiComponent);

    }

    // to make this extendible
    protected void renderPassThruAttrsAndEvents(FacesContext facesContext, UIComponent uiComponent) throws IOException
    {
        Map<String, List<ClientBehavior>> clientBehaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();

        Html5RendererUtils.renderPassThroughClientBehaviorEventHandlers(facesContext, uiComponent,
                getPassThroughClientBehaviorEvents(), clientBehaviors);

        Html5RendererUtils.renderPassThroughAttributes(facesContext.getResponseWriter(), uiComponent,
                getPassThroughAttributes());
    }

    protected abstract Map<String, String> getPassThroughClientBehaviorEvents();

    // package-private, since extensibility of this is not desired
    abstract String getHtmlElementName();

    protected abstract Map<String, String> getPassThroughAttributes();

    @Override
    public void encodeChildren(FacesContext facesContext, UIComponent uiComponent) throws IOException
    {
        // don't call super.encodeChildren(...), since it lets children to encode themselves
        if (log.isLoggable(Level.FINE))
            log.fine("encodeChildren");

        RendererUtils.checkParamValidity(facesContext, uiComponent, AbstractMedia.class);

        renderFallbackFacet(facesContext, uiComponent);

        renderMediaSources(facesContext, uiComponent);

    }

    @Override
    public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException
    {
        if (log.isLoggable(Level.FINE))
            log.fine("encodeEnd");
        // just close the element
        super.encodeEnd(facesContext, component);

        ResponseWriter writer = facesContext.getResponseWriter();

        writer.endElement(getHtmlElementName());
    }

    @Override
    public boolean getRendersChildren()
    {
        return true;
    }

    /**
     * Renders extracted media sources.
     */
    protected void renderMediaSources(FacesContext facesContext, UIComponent uiComponent) throws IOException
    {
        ResponseWriter writer = facesContext.getResponseWriter();

        // type check is done above with RendererUtils.checkParamValidity(...)
        AbstractMedia component = (AbstractMedia) uiComponent;

        // render MediaInfo instances
        Set<MediaInfo> mediaInfoSet = component.getMediaInfos();
        if (mediaInfoSet != null)
        {
            for (MediaInfo mediaInfo : mediaInfoSet)
            {
                if (mediaInfo.isDisabled())
                    continue;

                writer.startElement(HTML5.SOURCE_ELEM, null);

                // src is reqired to be present and not empty!
                if (mediaInfo.getSrc() == null || mediaInfo.getSrc().length() == 0)
                    // WIKI: add a wiki page
                    throw new FacesException("'src' field of MediaInfo has to be defined and nonempty for component " + DebugUtils.getPathToComponent(uiComponent) + ".");

                writer.writeAttribute(HTML5.SRC_ATTR, mediaInfo.getSrc(), null);

                String typeVal = _getTypeForSource(mediaInfo);
                if (typeVal != null) // write even if empty str
                    writer.writeAttribute(HTML5.TYPE_ATTR, typeVal, null);

                if (mediaInfo.getMedia() != null) // write even if empty str
                    writer.writeAttribute(HTML5.MEDIA_ATTR, mediaInfo.getMedia(), null);

                writer.endElement(HTML5.SOURCE_ELEM);
            }
        }
    }

    protected void renderFallbackFacet(FacesContext facesContext, UIComponent uiComponent) throws IOException
    {
        UIComponent fallbackFacet = uiComponent.getFacet(FACET_FALLBACK);
        if (fallbackFacet != null && fallbackFacet.isRendered())
        {
            if (log.isLoggable(Level.FINE))
                log.fine("rendering fallback facet");
            fallbackFacet.encodeAll(facesContext);
        }
    }

    /**
     * Returns the value of "type" attribute of Html5 <source> element. <br/>
     * e.g.: 'video/mp4;codecs="avc1.4D401E, mp4a.40.2"'
     */
    private String _getTypeForSource(MediaInfo mediaInfo)
    {
        String contentType = mediaInfo.getContentType();
        String codec = mediaInfo.getCodec();

        boolean contentTypeDefined = contentType != null && contentType.length() > 0;
        boolean codecDefined = codec != null && codec.length() > 0;

        // if codec is set, then contentType should be set too!
        if (codecDefined && !contentTypeDefined)
            // WIKI: add a wiki and ref it here
            throw new FacesException(
                    "'codec' is defined but 'contentType' is not. If 'codec' is defined, 'contentType' has to be defined too.");

        String retVal = null;
        if (contentTypeDefined)
        {
            StringBuilder builder = new StringBuilder();
            builder.append(contentType);
            // aliok: I tried <video> <source> with no codec on browser, and no problem experienced.
            if (codecDefined)
            {
                builder.append("; codec='").append(codec).append("'");
            }

            retVal = builder.toString();
        }

        return retVal;
    }

}
