package pl.edu.pw.mini.sg.solver.scipsolver

import pl.edu.pw.mini.sg.solver.SolverLinExpr

import scala.collection.mutable.ArrayBuffer

class ScipLinExpr extends SolverLinExpr[ScipVariable, ScipLinExprInner]{
  private val innerExpr = ScipLinExprInner(new ArrayBuffer[ScipVariable](), new ArrayBuffer[Double](), new ArrayBuffer[Double]())

  override def addTerm(coef: Double, variable: ScipVariable): Unit = {
    inner.termConsts.append(coef)
    inner.termVars.append(variable)
  }

  override def addTerms(coefs: Seq[Double], variables: Seq[ScipVariable]): Unit = {
    coefs.foreach(inner.termConsts.append(_))
    variables.foreach(inner.termVars.append(_))
  }

  override def addTerms(coefs: Double, variables: Seq[ScipVariable]): Unit = {
    variables.foreach(_ => inner.termConsts.append(coefs))
    variables.foreach(inner.termVars.append(_))
  }

  override def addConstant(c: Double): Unit = {
    inner.constants.append(c)
  }

  override val inner: ScipLinExprInner = innerExpr

  override def +(other: SolverLinExpr[ScipVariable, ScipLinExprInner]): ScipLinExpr = {
    val result = new ScipLinExpr

    inner.termConsts.foreach(result.inner.termConsts.append(_))
    inner.termVars.foreach(result.inner.termVars.append(_))

    other.inner.termConsts.foreach(result.inner.termConsts.append(_))
    other.inner.termVars.foreach(result.inner.termVars.append(_))

    result
  }

  override def +=(other: SolverLinExpr[ScipVariable, ScipLinExprInner]): Unit = {
    other.inner.termConsts.foreach(inner.termConsts.append(_))
    other.inner.termVars.foreach(inner.termVars.append(_))
  }
  override def -=(other: SolverLinExpr[ScipVariable, ScipLinExprInner]): Unit = {
    other.inner.termConsts.foreach(c => inner.termConsts.append(-c))
    other.inner.termVars.foreach(inner.termVars.append(_))
  }

  override def -(other: SolverLinExpr[ScipVariable, ScipLinExprInner]): ScipLinExpr = {
    val result = new ScipLinExpr

    inner.termConsts.foreach(result.inner.termConsts.append(_))
    inner.termVars.foreach(result.inner.termVars.append(_))

    other.inner.termConsts.foreach(c => inner.termConsts.append(-c))
    other.inner.termVars.foreach(inner.termVars.append(_))

    result
  }
}
