/**
 * Copyright 2005-2007 Xue Yong Zhi, Yu Su, Ye Zheng
 * Distributed under the GNU General Public License 2.0
 */

package com.xruby.runtime.builtin;

import com.xruby.runtime.lang.*;
import com.xruby.runtime.value.ObjectFactory;
import com.xruby.runtime.value.RubyArray;

/**
 * WARNING !!!
 * TODO: the implementation of Enumerable has a drawback, please take care if you wanna use it
 */

class Enum_collect extends RubyVarArgMethod {
    protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block) {
        RepeatableRubyBlock repeatableBlock = new RepeatableRubyBlock(block, receiver, getOwner());
        RubyAPI.callPublicMethod(receiver, args, repeatableBlock, CommonRubyID.eachID);
        return repeatableBlock.getRetValue();
    }
}

class Enum_all extends RubyVarArgMethod {
    protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block) {
        RepeatableRubyBlock repeatableBlock = new RepeatableRubyBlock(block, receiver, getOwner());
        RubyAPI.callPublicMethod(receiver, args, repeatableBlock, CommonRubyID.eachID);
        RubyArray array = repeatableBlock.getRetValue();

        for (RubyValue value : array) {
            // TODO: We should add RubyBoolean and its to_s
            if (value == ObjectFactory.FALSE_VALUE) {
                return ObjectFactory.FALSE_VALUE;
            }
        }
        return ObjectFactory.TRUE_VALUE;
    }
}

class Enum_any extends RubyVarArgMethod {
    protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block) {
        RepeatableRubyBlock repeatableBlock = new RepeatableRubyBlock(block, receiver, getOwner());
        RubyAPI.callPublicMethod(receiver, args, repeatableBlock, CommonRubyID.eachID);
        RubyArray array = repeatableBlock.getRetValue();

        for (RubyValue value : array) {
            // TODO: We should add RubyBoolean and its to_s
            if (value == ObjectFactory.TRUE_VALUE) {
                return ObjectFactory.TRUE_VALUE;
            }
        }
        return ObjectFactory.FALSE_VALUE;
    }
}

public class EnumerableModuleBuilder {
    public static void initialize() {
        RubyModule m = RubyRuntime.EnumerableModule;
        RubyMethod enum_collect = new Enum_collect();
        m.defineMethod("collect", enum_collect);
        m.defineMethod("map", enum_collect);
        m.defineMethod("all?", new Enum_all());
        m.defineMethod("any?", new Enum_any());
    }
}

@@ -394,24 +394,30 @@
 %0A%0Aclass Enum
+erable
 _collect ext
@@ -432,32 +432,32 @@
 yVarArgMethod %7B%0A
-
     protected Ru
@@ -772,24 +772,30 @@
 %0A%0Aclass Enum
+erable
 _all extends
@@ -1427,24 +1427,30 @@
 %0A%0Aclass Enum
+erable
 _any extends
@@ -2247,16 +2247,22 @@
 new Enum
+erable
 _collect
@@ -2398,16 +2398,22 @@
 new Enum
+erable
 _all());
@@ -2452,16 +2452,22 @@
 new Enum
+erable
 _any());

change class naming (Enum_* -> Enumerable_*)