import Element.elemabstract class Element{ def contents: Array[String] def height: Int = contents.length def width: Int = contents(0).length def above(that: Element): Element = { //new ArrayElement(this.contents ++ that.contents) val this1 = this widen that.width val that1 = that widen this.width elem(this1.contents ++ that1.contents) } def left_align(that: Element): Element = { if (this.width == that.width){ this above that } else if (this.width < that.width) { (this beside elem(' ', that.width - this.width, this.height)) above that } else { this above (that beside elem(' ', this.width - that.width, that.height)) } } def up_align(that: Element): Element = { if (this.height == that.height){ this beside that } else if (this.height < that.height) { (this above elem(' ', this.width, that.height - this.height)) beside that } else { this beside (that above elem(' ', that.width, this.height - that.height)) } } def beside(that: Element): Element = { val this1 = this heighten that.height val that1 = that heighten this.height elem( for ((line1, line2) <- this1.contents zip that1.contents) yield line1 + line2) } def widen(w: Int): Element = if(w <= width) this else { val left = Element.elem(' ', (w - width) / 2, height) var right = Element.elem(' ', w - width - left.width, height) left beside this beside right } def heighten(h: Int): Element = if (h <= height) this else { val top = Element.elem(' ', width, (h - height) / 2) val bot = Element.elem(' ', width, h - height - top.height) top above this above bot } override def toString = contents mkString "\n"}object Element { private class ArrayElement( val contents: Array[String] ) extends Element private class LineElement(s: String) extends Element { val contents = Array(s) override def width = s.length override def height = 1 } private class UniformElement( ch: Char, override val width: Int, override val height: Int ) extends Element { private val line = ch.toString * width def contents = Array.fill(height)(line) } def elem(contents: Array[String]): Element = new ArrayElement(contents) def elem(chr: Char, width: Int, height: Int): Element = new UniformElement(chr, width, height) def elem(line: String): Element = new LineElement(line)}