/*
 * Created by IntelliJ IDEA.
 * User: bungle
 * Date: 7.10.2002
 * Time: 19:23:47
 * To change template for new class use 
 * Code Style | Class Templates options (Tools | IDE Options).
 */
package com.projectcast.web.tools.velocity;

import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.StringWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

import webwork.action.ActionContext;
import webwork.action.SingleValueMap;

public class Global implements Tool {

    private Context context;
    private boolean odd = true;
    private boolean even = false;
    private Log log = LogFactory.getLog(this.getClass());

    public String evaluate(String value) {

        log.debug("Velocity is evaluating: " + value + ".");
        StringWriter writer = new StringWriter();

        try {
            Velocity.evaluate(this.context, writer, "com.projectcast.web.tools.velocity.Global", value);
            value = writer.toString();
        } catch (ParseErrorException e) {
            log.warn(e);
        } catch (MethodInvocationException e) {
            log.warn(e);
        } catch (ResourceNotFoundException e) {
            log.warn(e);
        } catch (IOException e) {
            log.warn(e);
        }

        return value;
    }

    public String getAlternatingRowColor() {

        if (this.odd) {
            this.setEven(true);
            return "odd";
        } else {
            this.setOdd(true);
            return "even";
        }
    }

    public void setContext(Context context) {
        this.context = context;
        this.setOdd(true);
    }

    public void setOdd(boolean odd) {
        this.odd = odd;
        this.even = !odd;
    }

    public boolean isOdd() {
        return this.odd;
    }

    public void setEven(boolean even) {
        this.even = even;
        this.odd = !even;
    }

    public boolean isEven() {
        return this.even;
    }

    public Map getMap() {
        return new HashMap();
    }

    public List getList() {
        return new ArrayList();
    }

    public Block getBlock() {
        return new Block();
    }

    public String cast(Object castable) {

        String returnValue = "";

        try {
            returnValue = (String) castable;
        } finally { }

        return returnValue.toString();
    }

    public String urlEncode(String text) {
        try {
            return java.net.URLEncoder.encode(text, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return text;
        }
    }

    public String makeURL(Collection c) {
        return makeURL(this.buildMap(c));
    }

    public String makeURL(Map params) {

        Map map = new HashMap();
        Map pm = new SingleValueMap(ActionContext.getContext().getParameters());

        String key, value;
        Iterator i = pm.keySet().iterator();

        while (i.hasNext()) {
            key = (String) i.next();
            value = (String) pm.get(key);
            map.put(key, value);
        }

        i = params.keySet().iterator();

        while (i.hasNext()) {
            key = (String) i.next();
            value = (String) params.get(key);
            map.put(key, value);
        }

        return (toURL(map));
    }

    public String makeURL() {
        return (toURL(ActionContext.getContext().getParameters()));
    }

    public String toURL(Map map) {

        Iterator i = map.keySet().iterator();
        StringBuffer buf = new StringBuffer("?");
        String key, value;

        do {
            if (!i.hasNext()) {
                break;
            }

            key = urlEncode((String) i.next());
            value = urlEncode((String) map.get(key));

            buf.append(key).append("=").append(value);

            if (i.hasNext()) {
                buf.append("&");
            }

        } while (true);

        return buf.toString();
    }

    public Map buildMap(Collection c) {

        Map map = new HashMap();

        Iterator i = c.iterator();

        String value;
        String[] property;

        while (i.hasNext()) {

            value = (String)i.next();
            property = value.split("=", 2);

            try {
                map.put(property[0], property[1]);
            } catch (ArrayIndexOutOfBoundsException e) {
                log.warn("Invalid value: " + value + ".");
            }
        }

        return map;
    }
}