package FolderSplit;

import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FolderChooser {
    final String config;
    
    private enum FormatFunctions {
        count {
            @Override public Object getObject(FileInfo file, int num) {
                return num;
            }
        },
        modified {
            @Override public Object getObject(FileInfo file, int num) {
                return file.modified;
            }
        };
       
        abstract Object getObject(FileInfo file, int num);
    }
    
    private enum StringFunctions {
        name {
            @Override public String getString(FileInfo file, int num) {
                return file.getFilename();
            }
        },
        extension {
            @Override public String getString(FileInfo file, int num) {
                return file.getExtension();
            }
        },
        fullname {
            @Override public String getString(FileInfo file, int num) {
                return file.name;
            }
        };
        
        abstract String getString(FileInfo file, int num);
    }
    
    public FolderChooser(String config) {
        this.config = config;
    }
    
    public String getFolder(FileInfo file, int num) {
        Matcher matcher = Pattern.compile("\\{([a-zA-Z]*)( [^}]+)*\\}").matcher(config);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String function = matcher.group(1).toLowerCase();
            String[] params = matcher.group(2) == null ? new String[0] : matcher.group(2).trim().split("[ ]+");
            replaceFormatFunction(file, num, matcher, sb, function, params);
            replaceStringFunction(file, num, matcher, sb, function, params);
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    private void replaceStringFunction(FileInfo file, int num, Matcher matcher, StringBuffer sb, String function, String[] params) {
        for (StringFunctions sf : StringFunctions.values()) {
            if (sf.name().equals(function)) {
                String s = sf.getString(file, num);
                s = applyStringParameters(params, s);
                matcher.appendReplacement(sb, s);
            }
        }
    }

    private String applyStringParameters(String[] params, String s) {
        for (int i = 0; i < params.length; i++) {
            String action = params[i];
            if (action.startsWith("substr")) {
                String[] startEnd = action.substring(6).split(",");
                int start = Integer.parseInt(startEnd[0]);
                if (start >= s.length()) {
                	s = "";
                	continue;
                }
                if (startEnd.length > 1) {
                    int end = Integer.parseInt(startEnd[1]);
                    if (end > s.length())
                    	end = s.length();
                    s = s.substring(start, end);
                } else {
                    s = s.substring(start);
                }
            } else if (action.equals("upper")) {
            	s = s.toUpperCase();
            } else if (action.equals("lower")) {
            	s = s.toLowerCase();
            } else if (action.startsWith("fb")) {
            	if (s.length() == 0)
            		s = action.substring(2);
            } 
        }
        return s;
    }

    private void replaceFormatFunction(FileInfo file, int num, Matcher matcher, StringBuffer sb, String function, String[] params) {
        for (FormatFunctions ff : FormatFunctions.values()) {
            if (ff.name().equals(function)) {
                String fmt = null;
                for (String p : params)
                    if (p.startsWith("%"))
                        fmt = p;
                Object o = ff.getObject(file, num);
                if (o instanceof Integer) {
                    o = applyIntegerParameters(params, o);
                    if (fmt == null)
                    	fmt = "%d";
                }
                if (o instanceof Date) {
                    if (fmt == null)
                    	fmt = "%1$tY-%1$tm-%1$td";
                }
                matcher.appendReplacement(sb, String.format(fmt, o));
            }
        }
    }

    private Object applyIntegerParameters(String[] params, Object o) {
        for (int i = 0; i < params.length; i++) {
            String action = params[i];
            if (action.startsWith("-") || action.startsWith("+")) {
                int dif = Integer.parseInt(action.startsWith("+") ? action.substring(1) : action);
                o = (Integer) o + dif;
            }
            if (action.startsWith("/")) {
                int dif = Integer.parseInt(action.substring(1));
                o = (Integer) o / dif;
            }
            if (action.startsWith("*")) {
                int dif = Integer.parseInt(action.substring(1));
                o = (Integer) o * dif;
            }
        }
        return o;
    }
}
