/*
 *******************************************************************************
 * Copyright (C) 2002-2012, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.util;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.text.UnicodeSetIterator;

public abstract class Visitor {
    
    public void doAt(Object item) {
        if (item instanceof Collection) {
            doAt((Collection) item);
        } else if (item instanceof Map) {
            doAt((Map) item);
        } else if (item instanceof Object[]) {
            doAt((Object[]) item);
        } else if (item instanceof UnicodeSet) {
            doAt((UnicodeSet) item);
        } else {
            doSimpleAt(item);
        }
    }

    public int count(Object item) {
        if (item instanceof Collection) {
            return ((Collection) item).size();
        } else if (item instanceof Map) {
            return ((Map) item).size();
        } else if (item instanceof Object[]) {
            return ((Object[]) item).length;
        } else if (item instanceof UnicodeSet) {
            return ((UnicodeSet) item).size();
        } else {
            return 1;
        }
    }

    // the default implementation boxing
    
    public void doAt(int o) {
        doSimpleAt(new Integer(o));
    }
    public void doAt(double o) {
        doSimpleAt(new Double(o));
    }
    public void doAt(char o) {
        doSimpleAt(new Character(o));
    }
    
    // for subclassing
    
    protected void doAt (Collection c) {
        if (c.size() == 0) doBefore(c, null);
        Iterator it = c.iterator();
        boolean first = true;
        Object last = null;
        while (it.hasNext()) {
            Object item = it.next();
            if (first) {
                doBefore(c, item);
                first = false;
            } else {
                doBetween(c, last, item);
            }    
            doAt(last=item);
        }
        doAfter(c, last);
    }

    protected void doAt (Map c) {
        doAt(c.entrySet());
    }

    protected void doAt (UnicodeSet c) {
        if (c.size() == 0) doBefore(c, null);
        UnicodeSetIterator it = new UnicodeSetIterator(c);
        boolean first = true;
        Object last = null;
        Object item;
        CodePointRange cpr0 = new CodePointRange();
        CodePointRange cpr1 = new CodePointRange();
        CodePointRange cpr;
        
        while(it.nextRange()) {
            if (it.codepoint == UnicodeSetIterator.IS_STRING) {
                item = it.string;
            } else {
                cpr = last == cpr0 ? cpr1 : cpr0;   // make sure we don't override last
                cpr.codepoint = it.codepoint;
                cpr.codepointEnd = it.codepointEnd;
                item = cpr;
            }           
            if (!first) {
                doBefore(c, item);
                first = true;
            } else {
                doBetween(c, last, item);
            }
            doAt(last = item);
        }
        doAfter(c, last);
    }
    
    protected void doAt (Object[] c) {
        doBefore(c, c.length == 0 ? null : c[0]);
        Object last = null;
        for (int i = 0; i < c.length; ++i) {
            if (i != 0) doBetween(c, last, c[i]);
            doAt(last = c[i]);
        }
        doAfter(c, last);
    }
    
    public static class CodePointRange{
        public int codepoint, codepointEnd;
    }
    
    // ===== MUST BE OVERRIDEN =====
    
    abstract protected void doBefore(Object container, Object item);
    abstract protected void doBetween(Object container, Object lastItem, Object nextItem);
    abstract protected void doAfter(Object container, Object item);   
    abstract protected void doSimpleAt(Object o);
    
}