package org.apache.slide.projector.processor.table;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.contract.Context;
import org.apache.commons.contract.Processor;
import org.apache.commons.contract.Result;
import org.apache.commons.contract.Store;
import org.apache.commons.contract.constraints.NumberConstraints;
import org.apache.commons.contract.constraints.StringConstraints;
import org.apache.commons.contract.descriptor.ParameterDescriptor;
import org.apache.commons.contract.descriptor.ResultDescriptor;
import org.apache.commons.contract.i18n.ParameterMessage;
import org.apache.slide.projector.Projector;
import org.apache.slide.projector.context.ProjectorContext;
import org.apache.slide.projector.engine.ProcessorManager;
import org.apache.slide.projector.value.URI;

/**
 * @version $Revision: 1.7 $
 */

public class TableHandler implements Processor {
    final static String URL = "tableHandler";

    final static String OK = "id";

    final static String ID = "id";
    final static String STORE = "store";
    final static String TARGET_POSITION = "targetPosition";
    final static String CURRENT_POSITION = "currentPosition";
    final static String SORTED_BY= "sortedBy";
    final static String ORDER= "order";
    final static String SIZE= "size";
    final static String EXPAND = "expand";
    final static String EXPANDED = "expanded";
    final static String COLLAPSE = "collapse";
    final static String COLLAPSED = "collapsed";

    final static String ASCENDING= "ascending";
    final static String DESCENDING= "descending";

    final static ParameterDescriptor[] parameterDescirptors = new ParameterDescriptor[] {
        new ParameterDescriptor(ID, new ParameterMessage("tableHandler/id"), new StringConstraints()),
        new ParameterDescriptor(TARGET_POSITION, new ParameterMessage("tableHandler/targetPosition"), new NumberConstraints(), null),
        new ParameterDescriptor(SORTED_BY, new ParameterMessage("tableHandler/sortedBy"), new StringConstraints(), null),
        new ParameterDescriptor(ORDER, new ParameterMessage("tableHandler/order"), new StringConstraints(new String[] {ASCENDING, DESCENDING}), null),
        new ParameterDescriptor(STORE, new ParameterMessage("tableHandler/store"), new StringConstraints(Projector.STORES)),
        new ParameterDescriptor(EXPAND, new ParameterMessage("tableHandler/expand"), new StringConstraints(), null),
        new ParameterDescriptor(COLLAPSE, new ParameterMessage("tableHandler/collapse"), new StringConstraints(), null)
    };
    private final static ResultDescriptor[] resultDescriptors = new ResultDescriptor[] {
            ResultDescriptor.OK
    };

    public Result process(Map parameter, Context context) throws Exception {
        String id = parameter.get(ID).toString();
        Store store = context.getStore(parameter.get(STORE).toString());
        Object targetPosition = parameter.get(TARGET_POSITION);
        Object sortedBy = parameter.get(SORTED_BY);
        Object order = parameter.get(ORDER);
        Object expand = parameter.get(EXPAND);
        Object collapse = parameter.get(COLLAPSE);
        Map tableMap = (Map)store.get(id, context);
        if ( tableMap == null) {
            tableMap = new HashMap();
            store.put(id, tableMap, context);
        }
        if ( targetPosition != null ) {
        	tableMap.put(CURRENT_POSITION, targetPosition);
        }
        if ( sortedBy != null ) {
            tableMap.put(SORTED_BY, sortedBy);
        }
        if ( order != null ) {
            tableMap.put(ORDER, order);
        }
        if ( collapse != null || expand != null ) {
        	Map size = (Map)tableMap.get(SIZE);
        	if ( size == null ) { 
        		tableMap.put(SIZE, new HashMap());
        	}
        	if ( collapse != null ) {
        		size.put(collapse.toString(), COLLAPSED);
        	}
        	if ( expand != null ) {
        		size.put(expand.toString(), EXPANDED);
        	}
        }
        URI bookmark = (URI)((ProjectorContext)context).getBookmark();
        if ( bookmark != null ) {
        	return ProcessorManager.getInstance().process(bookmark, parameter, context);
        } else {
        	return Result.OK;
        }
    }

    public ParameterDescriptor[] getParameterDescriptors() {
        return parameterDescirptors;
    }

    public ResultDescriptor[] getResultDescriptors() {
        return resultDescriptors;
    }
}