// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <zircon/device/display-controller.h>
#include <zircon/types.h>
#include <lib/zx/channel.h>

#include "display.h"
#include "fuchsia/hardware/display/c/fidl.h"
#include "image.h"

typedef struct frame {
    uint32_t width;
    uint32_t height;
    uint32_t x_pos;
    uint32_t y_pos;
} frame_t;

typedef struct layer {
    uint64_t id;
    bool active;

    bool done;

    frame_t src;
    frame_t dest;

    image_import_t import_info[2];
} layer_t;

// A layer whose output can appear on multiple displays.
class VirtualLayer {
public:
    explicit VirtualLayer(Display* display);
    explicit VirtualLayer(const fbl::Vector<Display>& displays);

    // Finish initializing the layer. All Set* methods should be called before this.
    virtual bool Init(zx_handle_t channel) = 0;

    // Steps the local layout state to frame_num.
    virtual void StepLayout(int32_t frame_num) = 0;

    // Waits for the display controller to be done with the previous version of this frame.
    virtual bool WaitForReady() = 0;

    // Sets the current layout to the display contorller.
    virtual void SendLayout(zx_handle_t channel) = 0;

    // Renders the current frame (and signals the fence if necessary).
    virtual void Render(int32_t frame_num) = 0;

    // Gets the display controller layer ID for usage on the given display.
    uint64_t id(uint64_t display_id) const {
        for (unsigned i = 0; i < displays_.size(); i++) {
            if (displays_[i]->id() == display_id && layers_[i].active) {
                return layers_[i].id;
            }
        }
        return INVALID_ID;
    }

    // Gets the ID of the image on the given display.
    virtual uint64_t image_id(uint64_t display_id) const = 0;

    void set_frame_done(uint64_t display_id) {
        for (unsigned i = 0; i < displays_.size(); i++) {
            if (displays_[i]->id() == display_id) {
                layers_[i].done = true;
            }
        }
    }

    virtual bool is_done() const {
        bool done = true;
        for (unsigned i = 0; i < displays_.size(); i++) {
            done &= !layers_[i].active || layers_[i].done;
        }
        return done;
    }

    void clear_done() {
        for (unsigned i = 0; i < displays_.size(); i++) {
            layers_[i].done = false;
        }
    }

protected:
    layer_t* CreateLayer(zx_handle_t dc_handle);
    void SetLayerImages(zx_handle_t handle, bool alt_image);

    fbl::Vector<Display*> displays_;
    fbl::Vector<layer_t> layers_;

    uint32_t width_;
    uint32_t height_;
};

class PrimaryLayer : public VirtualLayer {
public:
    explicit PrimaryLayer(Display* display);
    explicit PrimaryLayer(const fbl::Vector<Display>& displays);

    // Set* methods to configure the layer.
    void SetImageDimens(uint32_t width, uint32_t height) {
        image_width_ = width;
        image_height_ = height;

        src_frame_.width = width;
        src_frame_.height = height;
        dest_frame_.width = width;
        dest_frame_.height = height;
    }
    void SetSrcFrame(uint32_t width, uint32_t height) {
        src_frame_.width = width;
        src_frame_.height = height;
    }
    void SetDestFrame(uint32_t width, uint32_t height) {
        dest_frame_.width = width;
        dest_frame_.height = height;
    }
    void SetLayerFlipping(bool flip) { layer_flipping_ = flip; }
    void SetPanSrc(bool pan) { pan_src_ = pan; }
    void SetPanDest(bool pan) { pan_dest_ = pan; }
    void SetLayerToggle(bool toggle) { layer_toggle_ = toggle; }
    void SetRotates(bool rotates) { rotates_ = rotates; }
    void SetAlpha(bool enable, float val) {
        alpha_enable_ = enable;
        alpha_val_ = val;
    }
    void SetScaling(bool enable) {
        scaling_ = enable;
    }
    void SetImageFormat(uint32_t image_format) { image_format_ = image_format; }

    bool Init(zx_handle_t channel) override;
    void StepLayout(int32_t frame_num) override;
    bool WaitForReady() override;
    void SendLayout(zx_handle_t channel) override;
    void Render(int32_t frame_num) override;

    uint64_t image_id(uint64_t display_id) const override {
        for (unsigned i = 0; i < displays_.size(); i++) {
            if (displays_[i]->id() == display_id && layers_[i].active) {
                return layers_[i].import_info[alt_image_].id;
            }
        }
        return INVALID_ID;
    }

private:
    void SetLayerPositions(zx_handle_t handle);
    bool Wait(uint32_t idx);
    void InitImageDimens();

    uint32_t image_width_ = 0;
    uint32_t image_height_ = 0;
    uint32_t image_format_ = 0;
    frame_t src_frame_ = {};
    frame_t dest_frame_ = {};
    uint8_t rotation_ = fuchsia_hardware_display_Transform_IDENTITY;
    bool layer_flipping_ = false;
    bool pan_src_ = false;
    bool pan_dest_ = false;
    bool layer_toggle_ = false;
    bool rotates_ = false;
    bool alpha_enable_ = false;
    float alpha_val_ = 0.f;
    bool scaling_ = false;

    bool alt_image_ = false;
    Image* images_[2];
};

class CursorLayer : public VirtualLayer {
public:
    explicit CursorLayer(Display* display);
    explicit CursorLayer(const fbl::Vector<Display>& displays);

    bool Init(zx_handle_t channel) override;
    void StepLayout(int32_t frame_num) override;
    void SendLayout(zx_handle_t channel) override;

    bool WaitForReady() override { return true; }
    void Render(int32_t frame_num) override {}

    uint64_t image_id(uint64_t display_id) const override {
        for (unsigned i = 0; i < displays_.size(); i++) {
            if (displays_[i]->id() == display_id && layers_[i].active) {
                return layers_[i].import_info[0].id;
            }
        }
        return INVALID_ID;
    }


private:
    uint32_t x_pos_ = 0;
    uint32_t y_pos_ = 0;

    Image* image_;
};

class ColorLayer : public VirtualLayer {
public:
    explicit ColorLayer(Display* display);
    explicit ColorLayer(const fbl::Vector<Display>& displays);

    bool Init(zx_handle_t channel) override;

    void SendLayout(zx_handle_t channel) override {};
    void StepLayout(int32_t frame_num) override {};
    bool WaitForReady() override { return true; }
    void Render(int32_t frame_num) override {}
    uint64_t image_id(uint64_t display_id) const override { return INVALID_ID; }
    virtual bool is_done() const override { return true; }
};
