/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2019 Google LLC.
 *    All rights reserved.
 *
 *    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.
 */

#include <LcdPainter.h>

using namespace chip::app::Clusters::WindowCovering;

constexpr uint32_t sTiltIcon[] = {
    0xffffffff, 0xffffffff, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0000003, 0xc1ffffc3, 0xc1ffffc3,
    0xc1ffffc3, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003,
    0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003, 0xc003c003,
    0xc003c003, 0xc003c003, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0000003, 0xffffffff, 0xffffffff,
};

constexpr uint32_t sLiftIcon[] = {
    0xffffffff, 0xffffffff, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0f00003, 0xc0f00003,
    0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003,
    0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0f00003, 0xc0ffffc3,
    0xc0ffffc3, 0xc0ffffc3, 0xc0000003, 0xc0000003, 0xc0000003, 0xc0000003, 0xffffffff, 0xffffffff,
};

constexpr uint32_t sOneIcon[] = {
    0xffffffff, 0xffffffff, 0xc0000003, 0xc0000003, 0xc0000003, 0xc00fe003, 0xc01fe003, 0xc03fe003,
    0xc07fe003, 0xc0fbe003, 0xc1f3e003, 0xc3e3e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003,
    0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc003e003, 0xc3ffffc3,
    0xc3ffffc3, 0xc3ffffc3, 0xc3ffffc3, 0xc0000003, 0xc0000003, 0xc0000003, 0xffffffff, 0xffffffff,
};

constexpr uint32_t sTwoIcon[] = {
    0xffffffff, 0xffffffff, 0xc0000003, 0xc0000003, 0xc0000003, 0xc07ffe03, 0xc0ffff03, 0xc1ffff83,
    0xc3ffffc3, 0xc3f00fc3, 0xc3e007c3, 0xc3e007c3, 0xc00007c3, 0xc00007c3, 0xc0000fc3, 0xc00fff83,
    0xc03fff03, 0xc07ffe03, 0xc0fc0003, 0xc1f80003, 0xc1f00003, 0xc3e00003, 0xc3e00003, 0xc3ffffc3,
    0xc3ffffc3, 0xc3ffffc3, 0xc3ffffc3, 0xc0000003, 0xc0000003, 0xc0000003, 0xffffffff, 0xffffffff,
};

PixelPainter::PixelPainter(uint16_t lift, uint16_t tilt) : mLift(lift), mTilt(tilt) {}

CompositePainter::CompositePainter(uint16_t lift, uint16_t tilt, PixelPainter * painter1, PixelPainter * painter2,
                                   PixelPainter * painter3) :
    PixelPainter(lift, tilt),
    mPainter1(painter1), mPainter2(painter2), mPainter3(painter3)
{}

uint8_t CompositePainter::Color(uint32_t x, uint32_t y)
{
    int8_t pixel = -1;
    if (mPainter1)
    {
        pixel = mPainter1->Color(x, y);
        if (pixel >= 0)
        {
            return pixel;
        }
    }
    if (mPainter2)
    {
        pixel = mPainter2->Color(x, y);
        if (pixel >= 0)
        {
            return pixel;
        }
    }
    if (mPainter3)
    {
        pixel = mPainter3->Color(x, y);
        if (pixel >= 0)
        {
            return pixel;
        }
    }
    return pixel;
}

uint8_t FramePainter::Color(uint32_t x, uint32_t y)
{
    if (x < LCD_FRAME_SIZE || x >= (LCD_SIZE - LCD_FRAME_SIZE) || y < LCD_FRAME_SIZE || y >= (LCD_SIZE - LCD_FRAME_SIZE))
    {
        if (x < LCD_MARGIN_SIZE || x >= (LCD_SIZE - LCD_MARGIN_SIZE) || y < LCD_MARGIN_SIZE || y >= (LCD_SIZE - LCD_MARGIN_SIZE))
        {
            return 0;
        }
        else
        {
            return (x < (LCD_MARGIN_SIZE + LCD_BORDER_SIZE)) || (x >= (LCD_SIZE - LCD_BORDER_SIZE - LCD_MARGIN_SIZE)) ||
                (y < (LCD_MARGIN_SIZE + LCD_BORDER_SIZE)) || (y >= (LCD_SIZE - LCD_BORDER_SIZE - LCD_MARGIN_SIZE));
        }
    }
    return -1;
}

IconPainter::IconPainter(uint16_t lift, uint16_t tilt, LcdIcon icon) : PixelPainter(lift, tilt), mIcon(icon)
{
    mIconSize   = sizeof(sTiltIcon) / sizeof(uint32_t);
    mIconOffset = (LCD_SIZE - mIconSize) / 2;
}

uint8_t IconPainter::Color(uint32_t x, uint32_t y)
{
    const uint32_t * icon = nullptr;
    switch (mIcon)
    {
    case LcdIcon::One:
        icon = sOneIcon;
        break;
    case LcdIcon::Two:
        icon = sTwoIcon;
        break;
    case LcdIcon::Lift:
        icon = sLiftIcon;
        break;
    case LcdIcon::Tilt:
        icon = sTiltIcon;
        break;
    default:
        return -1;
    }
    if (x >= mIconOffset && x < (mIconOffset + mIconSize) && y >= mIconOffset && y < (mIconOffset + mIconSize))
    {
        uint32_t x0 = x - mIconOffset;
        uint32_t y0 = y - mIconOffset;
        return (icon[y0] & (1 << (31 - x0))) > 0;
    }
    return -1;
}

uint8_t VerticalShadePainter::Color(uint32_t x, uint32_t y)
{
    return (y % 2) && y < (uint32_t)(LCD_FRAME_SIZE + mLift);
}

uint8_t HorizontalShadePainter::Color(uint32_t x, uint32_t y)
{
    return (x % 2) && x < (uint32_t)(LCD_FRAME_SIZE + mLift);
}

VerticalBlindPainter::VerticalBlindPainter(uint16_t lift, uint16_t tilt) : PixelPainter(lift, tilt)
{
    mBandSize = (LCD_COVER_SIZE / sBandCount);
}

uint8_t VerticalBlindPainter::Color(uint32_t x, uint32_t y)
{
    if (x % 2)
    {
        return 0;
    }
    else
    {
        uint32_t closedCount = (mLift + 1) / mBandSize;
        uint32_t bandCount   = (y - LCD_FRAME_SIZE) / mBandSize;
        // ChipLogProgress(Zcl, "BLIND: ccount:%u, ccount:%u", clusterId);
        if (bandCount <= closedCount)
        {
            return y <= (LCD_FRAME_SIZE + mBandSize * bandCount + mTilt);
        }
        else
        {
            return 0;
        }
    }
}

PixelPainter * LcdPainter::GetCoverPainter(Type type, uint16_t lift, uint16_t tilt)
{
    switch (type)
    {
    case Type::kRollerShade:
    case Type::kRollerShade2Motor:
    case Type::kRollerShadeExterior:
    case Type::kRollerShadeExterior2Motor:
        return new VerticalShadePainter(lift, tilt);
    case Type::kDrapery:
    case Type::kAwning:
        return new HorizontalShadePainter(lift, tilt);
    case Type::kShutter:
    case Type::kTiltBlindTiltOnly:
    case Type::kTiltBlindLiftAndTilt:
        return new VerticalBlindPainter(lift, tilt);
    case Type::kProjectorScreen:
    case Type::kUnknown:
    default:
        return new VerticalShadePainter(lift, tilt);
    }

    return nullptr;
}

void LcdPainter::Paint(SilabsLCD & lcd, Type type, uint16_t lift, uint16_t tilt, LcdIcon icon)
{
    FramePainter framePaint         = FramePainter(lift, tilt);
    IconPainter iconPaint           = IconPainter(lift, tilt, icon);
    PixelPainter * coverPaint       = GetCoverPainter(type, lift, tilt);
    CompositePainter compositePaint = CompositePainter(lift, tilt, &framePaint, &iconPaint, coverPaint);
    void * context                  = lcd.Context();

    lcd.Clear();

    for (int i = 0; i < LCD_SIZE; i++)
    {
        for (int j = 0; j < LCD_SIZE; j++)
        {
            if (compositePaint.Color(i, j))
            {
                lcd.DrawPixel(context, i, j);
            }
        }
    }
    lcd.Update();
    delete coverPaint;
}
