/*
 * ListTransformer.java  $Revision: 1.2 $  $Date: 2007/10/03 04:39:40 $
 *
 * Copyright (C) 2007 Meldcraft Corporation
 *
 * This file is part of Scaffold.
 * 
 * Scaffold is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Scaffold is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Scaffold.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.meldcraft.application.data;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.script.Bindings;

import com.meldcraft.application.AbstractApplicationElement;
import com.meldcraft.application.ApplicationElementContext;
import com.meldcraft.application.util.BeanContext;
import com.meldcraft.application.util.BeanUtil;
import com.meldcraft.util.PropertiesHelper;
import com.meldcraft.util.ScriptExpander;

/**
 * @version $Revision: 1.2 $ $Date: 2007/10/03 04:39:40 $
 * @author Rob Richards
 */
public class ListTransformer extends AbstractApplicationElement implements DataTransformer
{
    protected Map       mConfig;
    protected String    mItems;
    protected Field[]   mFields;
    protected String    mInclude;

    public ListTransformer()
    {
    }

    public Object transformData(Object data)
    {
        ArrayList ret = new ArrayList();

        Object items = data;
        if (mItems != null)
        {
            items = BeanUtil.translateValue(new BeanContext(mApplicationElementContext.getApplicationContext(), items, mItems));
        }

        if (items instanceof Collection)
        {
            ScriptExpander scripter = new ScriptExpander();
            Collection col = (Collection)items;
            for (Object item: col)
            {
                addItem(ret, data, item, scripter);
            }
        }
        else if (items.getClass().isArray())
        {
            ScriptExpander scripter = new ScriptExpander();
            int len = Array.getLength(items);
            for (int i=0 ; i < len ; i++)
            {
                Object item = Array.get(items, i);
                addItem(ret, data, item, scripter);
            }
        }
        else if (items instanceof Enumeration)
        {
            ScriptExpander scripter = new ScriptExpander();
            Collection col = Collections.list((Enumeration)items);
            for (Object item: col)
            {
                addItem(ret, data, item, scripter);
            }
        }

        return ret;
    }

    @Override
    public void applicationInitialize(ApplicationElementContext context)
    {
        super.applicationInitialize(context);

        mConfig = context.getConfiguration();
        mItems = PropertiesHelper.getString(mConfig, "items", null);
        mInclude = PropertiesHelper.getString(mConfig, "includeItem", null);
        String[] fields = PropertiesHelper.getStringArray(mConfig, "fields");
        if (fields != null)
        {
            mFields = new Field[fields.length];
            for (int i=0 ; i < fields.length ; i++)
            {
                String field = fields[i];
                String pre = "field." + field;
                String name = PropertiesHelper.getString(mConfig, pre + ".name", field);
                String value = PropertiesHelper.getString(mConfig, pre + ".value", null);

                mFields[i] = new Field(name, value);
            }
        }
        
    }

    protected void addItem(List list, Object data, Object item, ScriptExpander scripter)
    {
        if (mFields != null)
        {
            Bindings bindings = scripter.getBindings();
            bindings.put("data", data);
            bindings.put("item", item);
            boolean include = true;
            if (mInclude != null)
            {
                Object obj = BeanUtil.translateValue(new BeanContext(mApplicationElementContext.getApplicationContext(), data, item, mInclude, scripter));
                include = (obj instanceof Boolean) && ((Boolean)obj).booleanValue();
            }

            if (include)
            {
                HashMap map = new HashMap();
                for (Field field: mFields)
                {
                    Object value = BeanUtil.translateValue(new BeanContext(mApplicationElementContext.getApplicationContext(), data, item, field.getValue(), scripter));
                    map.put(field.getName(), value);
                }
                list.add(map);
            }
        }
    }

    public static class Field
    {
        private String  mName;
        private String  mValue;

        public Field(String name, String value)
        {
            mName = name;
            mValue = value;
        }

        public String getName()
        {
            return mName;
        }

        public String getValue()
        {
            return mValue;
        }
    }
}



