package com.bradsdeals.clj.wrappers;

import java.util.Iterator;

import com.bradsdeals.clj.ClJ;
import com.coconut_palm_software.possible.Possible;

import clojure.lang.ISeq;

/**
 * A Seq implementation of {@link IClojureIterable}.
 * @author dorme
 */
public class ClojureSeq implements IClojureIterable<Object> {

    private ISeq delegate;

    /**
     * Constructor for ClojureSeq.
     * @param delegate The ISeq to wrap.
     */
    public ClojureSeq(ISeq delegate) {
        this.delegate = delegate;
    }

    /* (non-Javadoc)
     * @see java.lang.Iterable#iterator()
     */
    public Iterator<Object> iterator() {
        return new Iterator<Object>() {
            private Possible<ISeq> rest = Possible.emptyValue();

            private void init() {
                if (rest.isEmpty()) {
                    rest = Possible.value(delegate);
                }
            }

            public boolean hasNext() {
                init();
                return rest.get() != null;
            }

            public Object next() {
                Object result = rest.get().first();
                rest = Possible.value(rest.get().next());
                return ClJ.toJava(result);
            }};
    }

    /* (non-Javadoc)
     * @see com.bradsdeals.clj.wrappers.IClojureIterable#size()
     */
    public int size() {
        return delegate.count();
    }

    /* (non-Javadoc)
     * @see com.bradsdeals.clj.wrappers.IClojureIterable#isEmpty()
     */
    public boolean isEmpty() {
        return delegate.count() == 0;
    }

    /* (non-Javadoc)
     * @see com.bradsdeals.clj.wrappers.IClojureIterable#get(java.lang.Object)
     */
    public Object get(Object keyOrIndex) {
        return get(delegate, (Integer) keyOrIndex);
    }

    private Object get(ISeq current, int index) {
        if (index <= 0) {
            return current.first();
        } else {
            return get(current.next(), index=1);
        }
    }

    /* (non-Javadoc)
     * @see com.bradsdeals.clj.wrappers.IClojureIterable#toClojure()
     */
    public Object toClojure() {
        return delegate;
    }

}

@@ -90,16 +90,65 @@
 lj.ClJ;%0A
+import com.coconut_palm_software.possible.Nulls;%0A
 import c
@@ -751,134 +751,41 @@
 eq%3E 
-rest = Possible.emptyValue();%0A%0A            private void init() %7B%0A                if (rest.isEmpty()) %7B%0A                    res
+current; %7B%0A                curren
 t = 
@@ -814,26 +814,8 @@
 e);%0A
-                %7D%0A
     
@@ -868,32 +868,8 @@
 ) %7B%0A
-                init();%0A
     
@@ -891,26 +891,26 @@
 urn 
+cur
 re
-st.get() != null
+nt.hasValue()
 ;%0A  
@@ -989,19 +989,22 @@
 esult = 
+cur
 re
-s
+n
 t.get().
@@ -1032,33 +1032,39 @@
     
+cur
 re
-s
+n
 t = 
-Possible.value(res
+Nulls.possible(curren
 t.ge

Fix iterator boundary condition bug