/*  Exploring Languages with Interpreters and Functional Programming
    Copyright (C) 2019, H. Conrad Cunningham
    Modular Counting Program in Scala--Using trait and objects

1234567890123456789012345678901234567890123456789012345678901234567890

2019-01-28: Adapted from CountingMod.scala

*/

trait CountingIF {  // interface to "module"
    def setStart(start: Int) 
    def getStart: Int 
    def setStop(stop: Int)
    def getStop: Int
    def has_more(count: Int,maxc: Int): Boolean
    def incr 
    def counter
}

// implement interface with object or class
object CountingMod2 extends CountingIF {
    private var count =  0 
    private var maxc  = 10

    def setStart(start: Int) { // Use setters/getters
        count = start          // Should use special Scala syntax
    }

    def getStart: Int = count

    def setStop(stop: Int) {
        maxc = stop
    }

    def getStop: Int = maxc

    def has_more(c: Int, m: Int) = c <= m

    def incr {
        count = count + 1
    }

    def counter {
        while (has_more(count,maxc)) {
            println(count.toString)
            incr
        }
    }
}

// alternative implementation of interface
object CountingMod2a extends CountingIF {
    private var count =  0
    private var maxc  = 10

    def setStart(start: Int) {
        count = start
    }

    def getStart: Int = count

    def setStop(stop: Int) {
        maxc = stop
    }

    def getStop: Int = maxc

    def has_more(c: Int, m: Int) =
        c != 0 && Math.abs(c) <= Math.abs(m)

    def incr {
        count = count * 2
    }

    def counter {
        while (has_more(count,maxc)) {
            println(count.toString)
            incr
        }
    }
}


object CountingModTest2 {

    def main(args: Array[String]) {
        CountingMod2.counter
        println("[1..20]")
        CountingMod2a.setStart(1)
        CountingMod2a.setStop(20)
        CountingMod2a.counter
    }

}


