# Copyright (C) 2011 Dmitri Nikulin
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from common import SIZES, classname, mklabel, cells, startfile

def genmatrix(rows, cols):
    myclass = classname(rows, cols)
    fd = startfile("fixed", myclass)

    def line(s=""):
        print >> fd, s

    traits = [("Matrix_%d_N" % rows), ("Matrix_M_%d" % cols)]

    if (rows == cols):
        traits.append("Matrix_M_M")

    for trait in traits:
        line("import org.dnikulin.jula.traits.%s;" % trait)
    line()
    line("import org.dnikulin.jula.functions.Copy;")
    line()
    line("public final class %s implements %s {" % (myclass, ", ".join(traits)))
    line("    public static final int rows = %d;" % rows)
    line("    public static final int cols = %d;" % cols)
    line("    public static final int size = (rows * cols);")
    line()

    for row in range(rows):
        labels = ", ".join([mklabel(row, col) for col in range(cols)])
        line("    public double %s;" % labels)

    line()
    line("    @Override")
    line("    public int getRows() {")
    line("        return rows;")
    line("    }")

    line()
    line("    @Override")
    line("    public int getCols() {")
    line("        return cols;")
    line("    }")

    line()
    line("    @Override")
    line("    public double get(final int row, final int col) {")
    line("        assert(row >=    0);")
    line("        assert(col >=    0);")
    line("        assert(row <  rows);")
    line("        assert(col <  cols);")
    line()
    line("        switch ((row * cols) + col) {")
    for (row, col, label) in cells(rows, cols):
        off = (row * cols) + col
        line("            case %2d: return %s;" % (off, label))
    line("            default: return 0;")
    line("        }")
    line("    }")

    line()
    line("    @Override")
    line("    public void set(final int row, final int col, final double val) {")
    line("        assert(row >=    0);")
    line("        assert(col >=    0);")
    line("        assert(row <  rows);")
    line("        assert(col <  cols);")
    line()
    line("        switch ((row * cols) + col) {")
    for (row, col, label) in cells(rows, cols):
        off = (row * cols) + col
        line("            case %2d: %s = val; return;" % (off, label))
    line("            default: return;")
    line("        }")
    line("    }")

    line()
    line("    @Override")
    line("    public %s clone() {" % (myclass))
    line("        final %s that = new %s();" % (myclass, myclass))
    line("        Copy.copy(this, that);")
    line("        return that;")
    line("    }")
    line("}")

    fd.flush()
    fd.close()

if __name__ == '__main__':
    for rows in SIZES:
        for cols in SIZES:
            genmatrix(rows, cols)
