/*
 * 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.empire.jsf2.controls;

import java.io.IOException;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlInputTextarea;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;

import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.UnexpectedReturnValueException;
import org.apache.empire.jsf2.controls.InputControl.DisabledType;
import org.apache.empire.jsf2.controls.InputControl.ValueInfo;

public class TextAreaInputControl extends InputControl
{
    // private static final Logger log = LoggerFactory.getLogger(TextAreaInputControl.class);
    
    public static final String NAME = "textarea"; 
    
    public static final String FORMAT_COLS = "cols:";
    public static final String FORMAT_COLS_ATTRIBUTE = "format:cols";

    public static final String FORMAT_ROWS = "rows:";
    public static final String FORMAT_ROWS_ATTRIBUTE = "format:rows";
    
    private Class<? extends javax.faces.component.html.HtmlInputTextarea> inputComponentClass;

    public TextAreaInputControl(String name, Class<? extends HtmlInputTextarea> inputComponentClass)
    {
        super(name);
        this.inputComponentClass = inputComponentClass;
    }

    public TextAreaInputControl()
    {
        this(NAME, javax.faces.component.html.HtmlInputTextarea.class);
    }

    @Override
    public void renderValue(UIComponent comp, String tagName, String styleClass, String tooltip, ValueInfo vi, FacesContext context)
            throws IOException
    {
        // cols
        int cols = getFormatInteger(vi, FORMAT_COLS, FORMAT_COLS_ATTRIBUTE);
        if (cols>0)
            styleClass += " cols"+String.valueOf(cols);
        // rows
        int rows = getFormatInteger(vi, FORMAT_ROWS, FORMAT_ROWS_ATTRIBUTE);
        if (rows>0)
            styleClass += " rows"+String.valueOf(rows);
        // render
        super.renderValue(comp, tagName, styleClass, tooltip, vi, context);
    }
    
    @Override
    protected void createInputComponents(UIComponent parent, InputInfo ii, FacesContext context, List<UIComponent> compList)
    {
        // check params
        if (!compList.isEmpty())
            throw new InvalidArgumentException("compList", compList);
        // create
        HtmlInputTextarea input = InputControlManager.createComponent(context, this.inputComponentClass);
        // once
        copyAttributes(parent, ii, input);
        // cols
        int cols = getFormatInteger(ii, FORMAT_COLS, FORMAT_COLS_ATTRIBUTE);
        if (cols>0)
            input.setCols(cols);
        // rows
        int rows = getFormatInteger(ii, FORMAT_ROWS, FORMAT_ROWS_ATTRIBUTE);
        if (rows>0)
            input.setRows(rows);
        // add
        compList.add(input);
        // update
        updateInputState(compList, ii, context, context.getCurrentPhaseId());
    }
    
    @Override
    protected void updateInputState(List<UIComponent> compList, InputInfo ii, FacesContext context, PhaseId phaseId)
    {
        UIComponent comp = compList.get(0);
        if (!(comp instanceof HtmlInputTextarea))
        {
            throw new UnexpectedReturnValueException(comp.getClass().getName(), "compList.get(0)");
        }
        HtmlInputTextarea input = (HtmlInputTextarea)comp;
        // disabled
        DisabledType disabled = ii.getDisabled();
        if (disabled!=null)
        {   input.setReadonly((disabled==DisabledType.READONLY));
            input.setDisabled((disabled==DisabledType.DISABLED));
        }
        // Set Value
        if (phaseId==PhaseId.RENDER_RESPONSE)
        {   // style
            addRemoveDisabledStyle(input, (disabled!=null && disabled!=DisabledType.NO));
            addRemoveInvalidStyle(input, ii.hasError());
            // set value
            setInputValue(input, ii);
        }    
    }

    @Override
    protected String formatValue(Object value, ValueInfo vi)
    {
        String strVal = super.formatValue(value, vi);
        // replace CR/LF by <BR/>
        if (strVal.indexOf("\r\n")>0)
        {   // replace CR with <BR/>
            strVal = StringUtils.replace(strVal, "\r\n", "<BR/>\n");
        }
        else if (strVal.indexOf('\n')>0)
        {   // replace CR with <BR/>
            strVal = StringUtils.replace(strVal, "\n", "<BR/>\n");
        }
        return strVal; 
    }

    @Override
    protected Object parseInputValue(String value, InputInfo ii)
    {
        // Trim
        if (hasFormatOption(ii, "notrim")==false)
            value = value.trim();
        // Done 
        return value; 
    }
    
}
