/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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.
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;

public class GenerateGLES {

    static void copy(String filename, PrintStream out) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(filename));
        String s;
        while ((s = br.readLine()) != null) {
            out.println(s);
        }
    }

    private static void emit(GLESCodeEmitter emitter,
                             BufferedReader specReader,
                             PrintStream glStream,
                             PrintStream cStream) throws Exception {
        String s = null;
        while ((s = specReader.readLine()) != null) {
            if (s.trim().startsWith("//")) {
                continue;
            }

            CFunc cfunc = CFunc.parseCFunc(s);
            String fname = cfunc.getName();
            String stubRoot = "stubs/gles11/" + fname;
            String javaPath = stubRoot + ".java";
            File f = new File(javaPath);
            if (f.exists()) {
                System.out.println("Special-casing function " + fname);
                copy(javaPath, glStream);
                copy(stubRoot + ".cpp", cStream);

                // Register native function names
                // This should be improved to require fewer discrete files
                String filename = stubRoot + ".nativeReg";
                BufferedReader br =
                    new BufferedReader(new FileReader(filename));
                String nfunc;
                while ((nfunc = br.readLine()) != null) {
                    emitter.addNativeRegistration(nfunc);
                }
            } else {
                emitter.emitCode(cfunc, s);
            }
        }
    }

    public static void main(String[] args) throws Exception {
        int aidx = 0;
        while ((aidx < args.length) && (args[aidx].charAt(0) == '-')) {
            switch (args[aidx].charAt(1)) {
            default:
                System.err.println("Unknown flag: " + args[aidx]);
                System.exit(1);
            }

            aidx++;
        }

        BufferedReader checksReader =
            new BufferedReader(new FileReader("specs/gles11/checks.spec"));
        ParameterChecker checker = new ParameterChecker(checksReader);

        // Generate files
        for(String suffix: new String[] {"GLES10", "GLES10Ext",
                "GLES11", "GLES11Ext", "GLES20",
                "GLES30", "GLES31", "GLES31Ext", "GLES32"})
        {
            BufferedReader spec11Reader =
                new BufferedReader(new FileReader("specs/gles11/"
                        + suffix + ".spec"));
            String gl11Filename = "android/opengl/" + suffix + ".java";
            String gl11cFilename = "android_opengl_" + suffix + ".cpp";
            PrintStream gl11Stream =
                new PrintStream(new FileOutputStream("out/" + gl11Filename));
            PrintStream gl11cStream =
                new PrintStream(new FileOutputStream("out/" + gl11cFilename));
            copy("stubs/gles11/" + suffix + "Header.java-if", gl11Stream);
            copy("stubs/gles11/" + suffix + "cHeader.cpp", gl11cStream);
            copy("stubs/gles11/common.cpp", gl11cStream);
            GLESCodeEmitter emitter = new GLESCodeEmitter(
                    "android/opengl/" + suffix,
                    checker, gl11Stream, gl11cStream);
            emit(emitter, spec11Reader, gl11Stream, gl11cStream);
            emitter.emitNativeRegistration("register_android_opengl_jni_"
                    + suffix);
            gl11Stream.println("}");
            gl11Stream.close();
            gl11cStream.close();
        }
    }
}
