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

#ifndef SKSL_DSL_VAR
#define SKSL_DSL_VAR

#include "include/sksl/DSLExpression.h"
#include "include/sksl/DSLModifiers.h"
#include "include/sksl/DSLType.h"

namespace SkSL {

class IRGenerator;
class SPIRVCodeGenerator;
class Variable;
enum class VariableStorage : int8_t;

namespace dsl {

class DSLVarBase {
public:
    /**
     * Creates an empty, unpopulated var. Can be replaced with a real var later via `swap`.
     */
    DSLVarBase() : fType(kVoid_Type), fDeclared(true) {}

    /**
     * Constructs a new variable with the specified type and name. The name is used (in mangled
     * form) in the resulting shader code; it is not otherwise important. Since mangling prevents
     * name conflicts and the variable's name is only important when debugging shaders, the name
     * parameter is optional.
     */
    DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue);

    DSLVarBase(DSLType type, DSLExpression initialValue);

    DSLVarBase(DSLModifiers modifiers, DSLType type, skstd::string_view name,
               DSLExpression initialValue);

    DSLVarBase(DSLModifiers modifiers, DSLType type, DSLExpression initialValue);

    DSLVarBase(DSLVarBase&&) = default;

    virtual ~DSLVarBase();

    skstd::string_view name() const {
        return fName;
    }

    DSLModifiers modifiers() const {
        return fModifiers;
    }

    virtual VariableStorage storage() const = 0;

    DSLExpression x() {
        return DSLExpression(*this).x();
    }

    DSLExpression y() {
        return DSLExpression(*this).y();
    }

    DSLExpression z() {
        return DSLExpression(*this).z();
    }

    DSLExpression w() {
        return DSLExpression(*this).w();
    }

    DSLExpression r() {
        return DSLExpression(*this).r();
    }

    DSLExpression g() {
        return DSLExpression(*this).g();
    }

    DSLExpression b() {
        return DSLExpression(*this).b();
    }

    DSLExpression a() {
        return DSLExpression(*this).a();
    }

    DSLExpression field(skstd::string_view name) {
        return DSLExpression(*this).field(name);
    }

    DSLPossibleExpression operator[](DSLExpression&& index);

    DSLPossibleExpression operator++() {
        return ++DSLExpression(*this);
    }

    DSLPossibleExpression operator++(int) {
        return DSLExpression(*this)++;
    }

    DSLPossibleExpression operator--() {
        return --DSLExpression(*this);
    }

    DSLPossibleExpression operator--(int) {
        return DSLExpression(*this)--;
    }

protected:
    DSLPossibleExpression assign(DSLExpression other);

    void swap(DSLVarBase& other);

    DSLModifiers fModifiers;
    // We only need to keep track of the type here so that we can create the SkSL::Variable. For
    // predefined variables this field is unnecessary, so we don't bother tracking it and just set
    // it to kVoid; in other words, you shouldn't generally be relying on this field to be correct.
    // If you need to determine the variable's type, look at DSLWriter::Var(...)->type() instead.
    DSLType fType;
    int fUniformHandle = -1;
    std::unique_ptr<SkSL::Statement> fDeclaration;
    const SkSL::Variable* fVar = nullptr;
    skstd::string_view fRawName; // for error reporting
    skstd::string_view fName;
    DSLExpression fInitialValue;
    bool fDeclared = false;

    friend class DSLCore;
    friend class DSLExpression;
    friend class DSLFunction;
    friend class DSLWriter;
    friend class ::SkSL::IRGenerator;
    friend class ::SkSL::SPIRVCodeGenerator;
};

/**
 * A local variable.
 */
class DSLVar : public DSLVarBase {
public:
    DSLVar() = default;

    DSLVar(DSLType type, skstd::string_view name = "var",
           DSLExpression initialValue = DSLExpression())
        : INHERITED(type, name, std::move(initialValue)) {}

    DSLVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression())
        : DSLVar(type, skstd::string_view(name), std::move(initialValue)) {}

    DSLVar(DSLType type, DSLExpression initialValue)
        : INHERITED(type, std::move(initialValue)) {}

    DSLVar(DSLModifiers modifiers, DSLType type, skstd::string_view name = "var",
           DSLExpression initialValue = DSLExpression())
        : INHERITED(modifiers, type, name, std::move(initialValue)) {}

    DSLVar(DSLModifiers modifiers, DSLType type, const char* name,
           DSLExpression initialValue = DSLExpression())
        : DSLVar(modifiers, type, skstd::string_view(name), std::move(initialValue)) {}

    DSLVar(DSLVar&&) = default;

    VariableStorage storage() const override;

    void swap(DSLVar& other);

    DSLPossibleExpression operator=(DSLExpression expr);

    DSLPossibleExpression operator=(DSLVar& param) {
        return this->operator=(DSLExpression(param));
    }

    template<class Param>
    DSLPossibleExpression operator=(Param& param) {
        return this->operator=(DSLExpression(param));
    }

private:
    using INHERITED = DSLVarBase;
};

/**
 * A global variable.
 */
class DSLGlobalVar : public DSLVarBase {
public:
    DSLGlobalVar() = default;

    DSLGlobalVar(DSLType type, skstd::string_view name = "var",
           DSLExpression initialValue = DSLExpression())
        : INHERITED(type, name, std::move(initialValue)) {}

    DSLGlobalVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression())
        : DSLGlobalVar(type, skstd::string_view(name), std::move(initialValue)) {}

    DSLGlobalVar(DSLType type, DSLExpression initialValue)
        : INHERITED(type, std::move(initialValue)) {}

    DSLGlobalVar(DSLModifiers modifiers, DSLType type, skstd::string_view name = "var",
           DSLExpression initialValue = DSLExpression())
        : INHERITED(modifiers, type, name, std::move(initialValue)) {}

    DSLGlobalVar(DSLModifiers modifiers, DSLType type, const char* name,
           DSLExpression initialValue = DSLExpression())
        : DSLGlobalVar(modifiers, type, skstd::string_view(name), std::move(initialValue)) {}

    DSLGlobalVar(const char* name);

    DSLGlobalVar(DSLGlobalVar&&) = default;

    VariableStorage storage() const override;

    void swap(DSLGlobalVar& other);

    DSLPossibleExpression operator=(DSLExpression expr);

    DSLPossibleExpression operator=(DSLGlobalVar& param) {
        return this->operator=(DSLExpression(param));
    }

    template<class Param>
    DSLPossibleExpression operator=(Param& param) {
        return this->operator=(DSLExpression(param));
    }

private:
    using INHERITED = DSLVarBase;
};

/**
 * A function parameter.
 */
class DSLParameter : public DSLVarBase {
public:
    DSLParameter() = default;

    DSLParameter(DSLType type, skstd::string_view name = "var")
        : INHERITED(type, name, DSLExpression()) {}

    DSLParameter(DSLType type, const char* name)
        : DSLParameter(type, skstd::string_view(name)) {}

    DSLParameter(DSLModifiers modifiers, DSLType type, skstd::string_view name = "var")
        : INHERITED(modifiers, type, name, DSLExpression()) {}

    DSLParameter(DSLModifiers modifiers, DSLType type, const char* name)
        : DSLParameter(modifiers, type, skstd::string_view(name)) {}

    DSLParameter(DSLParameter&&) = default;

    VariableStorage storage() const override;

    void swap(DSLParameter& other);

    DSLPossibleExpression operator=(DSLExpression expr);

    DSLPossibleExpression operator=(DSLParameter& param) {
        return this->operator=(DSLExpression(param));
    }

    template<class Param>
    DSLPossibleExpression operator=(Param& param) {
        return this->operator=(DSLExpression(param));
    }

private:
    using INHERITED = DSLVarBase;
};

} // namespace dsl

} // namespace SkSL


#endif
