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

#ifndef SKSL_MODIFIERS
#define SKSL_MODIFIERS

#include "include/private/SkSLLayout.h"

#include <cstddef>
#include <memory>
#include <string>

namespace SkSL {

class Context;
class Position;

/**
 * A set of modifier keywords (in, out, uniform, etc.) appearing before a declaration.
 */
struct Modifiers {
    /**
     * OpenGL requires modifiers to be in a strict order:
     * - invariant-qualifier:     (invariant)
     * - interpolation-qualifier: flat, noperspective, (smooth)
     * - storage-qualifier:       const, uniform
     * - parameter-qualifier:     in, out, inout
     * - precision-qualifier:     highp, mediump, lowp
     *
     * SkSL does not have `invariant` or `smooth`.
     */

    enum Flag {
        kNo_Flag             =       0,
        // Real GLSL modifiers
        kFlat_Flag           = 1 <<  0,
        kNoPerspective_Flag  = 1 <<  1,
        kConst_Flag          = 1 <<  2,
        kUniform_Flag        = 1 <<  3,
        kIn_Flag             = 1 <<  4,
        kOut_Flag            = 1 <<  5,
        kHighp_Flag          = 1 <<  6,
        kMediump_Flag        = 1 <<  7,
        kLowp_Flag           = 1 <<  8,
        // We use the Metal name for this one (corresponds to the GLSL 'shared' modifier)
        kThreadgroup_Flag    = 1 <<  9,
        // SkSL extensions, not present in GLSL
        kES3_Flag            = 1 << 10,
        kHasSideEffects_Flag = 1 << 11,
        kInline_Flag         = 1 << 12,
        kNoInline_Flag       = 1 << 13,
    };

    Modifiers()
    : fLayout(Layout())
    , fFlags(0) {}

    Modifiers(const Layout& layout, int flags)
    : fLayout(layout)
    , fFlags(flags) {}

    std::string description() const {
        std::string result = fLayout.description();

        // SkSL extensions
        if (fFlags & kES3_Flag) {
            result += "$es3 ";
        }
        if (fFlags & kHasSideEffects_Flag) {
            result += "sk_has_side_effects ";
        }
        if (fFlags & kNoInline_Flag) {
            result += "noinline ";
        }

        // Real GLSL qualifiers (must be specified in order in GLSL 4.1 and below)
        if (fFlags & kFlat_Flag) {
            result += "flat ";
        }
        if (fFlags & kNoPerspective_Flag) {
            result += "noperspective ";
        }
        if (fFlags & kConst_Flag) {
            result += "const ";
        }
        if (fFlags & kUniform_Flag) {
            result += "uniform ";
        }
        if ((fFlags & kIn_Flag) && (fFlags & kOut_Flag)) {
            result += "inout ";
        } else if (fFlags & kIn_Flag) {
            result += "in ";
        } else if (fFlags & kOut_Flag) {
            result += "out ";
        }
        if (fFlags & kHighp_Flag) {
            result += "highp ";
        }
        if (fFlags & kMediump_Flag) {
            result += "mediump ";
        }
        if (fFlags & kLowp_Flag) {
            result += "lowp ";
        }

        // We're using a non-GLSL name for this one; the GLSL equivalent is "shared"
        if (fFlags & kThreadgroup_Flag) {
            result += "threadgroup ";
        }

        return result;
    }

    bool operator==(const Modifiers& other) const {
        return fLayout == other.fLayout && fFlags == other.fFlags;
    }

    bool operator!=(const Modifiers& other) const {
        return !(*this == other);
    }

    /**
     * Verifies that only permitted modifiers and layout flags are included. Reports errors and
     * returns false in the event of a violation.
     */
    bool checkPermitted(const Context& context, Position pos, int permittedModifierFlags,
            int permittedLayoutFlags) const;

    Layout fLayout;
    int fFlags;
};

} // namespace SkSL

namespace std {

template <>
struct hash<SkSL::Modifiers> {
    size_t operator()(const SkSL::Modifiers& key) const {
        return (size_t) key.fFlags ^ ((size_t) key.fLayout.fFlags << 8) ^
               ((size_t) key.fLayout.fBuiltin << 16);
    }
};

} // namespace std

#endif
