/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SKSL_HCODEGENERATOR
#define SKSL_HCODEGENERATOR

#include "src/sksl/SkSLCodeGenerator.h"
#include "src/sksl/SkSLSectionAndParameterHelper.h"
#include "src/sksl/ir/SkSLType.h"
#include "src/sksl/ir/SkSLVariable.h"

#include <cctype>

#if defined(SKSL_STANDALONE) || GR_TEST_UTILS

constexpr const char* kFragmentProcessorHeader =
R"(
/**************************************************************************************************
 *** This file was autogenerated from %s.fp; do not modify.
 **************************************************************************************************/
)";

namespace SkSL {

class HCodeGenerator : public CodeGenerator {
public:
    HCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
                   String name, OutputStream* out);

    bool generateCode() override;

    static String ParameterType(const Context& context, const Type& type, const Layout& layout);

    static Layout::CType ParameterCType(const Context& context, const Type& type,
                                        const Layout& layout);

    static String FieldType(const Context& context, const Type& type, const Layout& layout);

    // Either the field type, or a const reference of the field type if the field type is complex.
    static String AccessType(const Context& context, const Type& type, const Layout& layout);

    static String FieldName(const char* varName) {
        return String(varName);
    }

    static String CoordTransformName(const String& arg, int index) {
        if (arg.size()) {
            return HCodeGenerator::FieldName(arg.c_str()) + "CoordTransform";
        }
        return "fCoordTransform" + to_string(index);
    }

    static String GetHeader(const Program& program, ErrorReporter& errors);

private:
    void writef(const char* s, va_list va) SK_PRINTF_LIKE(2, 0);

    void writef(const char* s, ...) SK_PRINTF_LIKE(2, 3);

    bool writeSection(const char* name, const char* prefix = "");

    // given a @constructorParams section of e.g. 'int x, float y', writes out "<separator>x, y".
    // Writes nothing (not even the separator) if there is no @constructorParams section.
    void writeExtraConstructorParams(const char* separator);

    void writeMake();

    void writeConstructor();

    void writeFields();

    void failOnSection(const char* section, const char* msg);

    const Context& fContext;
    String fName;
    String fFullName;
    SectionAndParameterHelper fSectionAndParameterHelper;

    using INHERITED = CodeGenerator;
};

} // namespace SkSL

#endif // defined(SKSL_STANDALONE) || GR_TEST_UTILS

#endif // SKSL_HCODEGENERATOR
