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

#include "gm.h"
#include "SkCanvas.h"
#include "SkRSXform.h"
#include "SkSurface.h"

// Create a square atlas of:
//   opaque white  |     opaque red
//  ------------------------------------
//   opaque green  |  transparent black
//
static SkImage* make_atlas(SkCanvas* caller, int atlasSize) {
    const int kBlockSize = atlasSize/2;

    SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize);
    SkAutoTUnref<SkSurface> surface(caller->newSurface(info));
    if (nullptr == surface) {
        surface.reset(SkSurface::NewRaster(info));
    }
    SkCanvas* canvas = surface->getCanvas();

    SkPaint paint;
    paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode));

    paint.setColor(SK_ColorWHITE);
    SkRect r = SkRect::MakeXYWH(0, 0, 
                                SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
    canvas->drawRect(r, paint);

    paint.setColor(SK_ColorRED);
    r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), 0, 
                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
    canvas->drawRect(r, paint);

    paint.setColor(SK_ColorGREEN);
    r = SkRect::MakeXYWH(0, SkIntToScalar(kBlockSize), 
                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
    canvas->drawRect(r, paint);

    paint.setColor(SK_ColorTRANSPARENT);
    r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize), 
                         SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
    canvas->drawRect(r, paint);

    return surface->newImageSnapshot();
}

// This GM tests the drawAtlas API with colors, different xfer modes
// and transparency in the atlas image
class DrawAtlasColorsGM : public skiagm::GM {
public:
    DrawAtlasColorsGM() {
        this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
    }
    
protected:
    SkString onShortName() override {
        return SkString("draw-atlas-colors");
    }
    
    SkISize onISize() override {
        return SkISize::Make(kNumXferModes * (kAtlasSize + kPad) + kPad,
                             2 * kNumColors * (kAtlasSize + kPad) + kTextPad + kPad);
    }
    
    void onDraw(SkCanvas* canvas) override {
        const SkRect target = SkRect::MakeWH(SkIntToScalar(kAtlasSize), SkIntToScalar(kAtlasSize));

        if (nullptr == fAtlas) {
            fAtlas.reset(make_atlas(canvas, kAtlasSize));
        }

        const struct {
            SkXfermode::Mode fMode;
            const char*      fLabel;
        } gModes[] = {
            { SkXfermode::kClear_Mode,      "Clear"     },
            { SkXfermode::kSrc_Mode,        "Src"       },
            { SkXfermode::kDst_Mode,        "Dst"       },
            { SkXfermode::kSrcOver_Mode,    "SrcOver"   },
            { SkXfermode::kDstOver_Mode,    "DstOver"   },
            { SkXfermode::kSrcIn_Mode,      "SrcIn"     },
            { SkXfermode::kDstIn_Mode,      "DstIn"     },
            { SkXfermode::kSrcOut_Mode,     "SrcOut"    },
            { SkXfermode::kDstOut_Mode,     "DstOut"    },
            { SkXfermode::kSrcATop_Mode,    "SrcATop"   },
            { SkXfermode::kDstATop_Mode,    "DstATop"   },
            { SkXfermode::kXor_Mode,        "Xor"       },
            { SkXfermode::kPlus_Mode,       "Plus"      },
            { SkXfermode::kModulate_Mode,   "Mod"       },
            { SkXfermode::kScreen_Mode,     "Screen"    },
            { SkXfermode::kOverlay_Mode,    "Overlay"   },
            { SkXfermode::kDarken_Mode,     "Darken"    },
            { SkXfermode::kLighten_Mode,    "Lighten"   },
            { SkXfermode::kColorDodge_Mode, "Dodge"     },
            { SkXfermode::kColorBurn_Mode,  "Burn"      },
            { SkXfermode::kHardLight_Mode,  "Hard"      },
            { SkXfermode::kSoftLight_Mode,  "Soft"      },
            { SkXfermode::kDifference_Mode, "Diff"      },
            { SkXfermode::kExclusion_Mode,  "Exclusion" },
            { SkXfermode::kMultiply_Mode,   "Multiply"  },
            { SkXfermode::kHue_Mode,        "Hue"       },
            { SkXfermode::kSaturation_Mode, "Sat"       },
            { SkXfermode::kColor_Mode,      "Color"     },
            { SkXfermode::kLuminosity_Mode, "Luminosity"},
        };

        SkColor gColors[] = {
            SK_ColorWHITE,
            SK_ColorRED,
            0x88888888,         // transparent grey
            0x88000088          // transparent blue
        };

        const int numModes = SK_ARRAY_COUNT(gModes);
        SkASSERT(numModes == kNumXferModes);
        const int numColors = SK_ARRAY_COUNT(gColors);
        SkASSERT(numColors == kNumColors);
        SkRSXform xforms[numColors];
        SkRect rects[numColors];
        SkColor quadColors[numColors];

        SkPaint paint;
        paint.setAntiAlias(true);

        for (int i = 0; i < numColors; ++i) {
            xforms[i].set(1.0f, 0.0f, SkIntToScalar(kPad), i*(target.width()+kPad));
            rects[i] = target;
            quadColors[i] = gColors[i];
        }

        SkPaint textP;
        textP.setTextSize(SkIntToScalar(kTextPad));
        textP.setAntiAlias(true);
        sk_tool_utils::set_portable_typeface(&textP, nullptr);

        for (int i = 0; i < numModes; ++i) {
            canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
                             i*(target.width()+kPad)+kPad, SkIntToScalar(kTextPad),
                             textP);
        }

        for (int i = 0; i < numModes; ++i) {
            canvas->save();            
            canvas->translate(SkIntToScalar(i*(target.height()+kPad)),
                              SkIntToScalar(kTextPad+kPad));
            // w/o a paint
            canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors, 
                              gModes[i].fMode, nullptr, nullptr);
            canvas->translate(0.0f, numColors*(target.height()+kPad));
            // w a paint
            canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors, 
                              gModes[i].fMode, nullptr, &paint);
            canvas->restore();        
        }
    }
    
private:
    static const int kNumXferModes = 29;
    static const int kNumColors = 4;
    static const int kAtlasSize = 30;
    static const int kPad = 2;
    static const int kTextPad = 8;


    SkAutoTUnref<SkImage> fAtlas;

    typedef GM INHERITED;
};
DEF_GM( return new DrawAtlasColorsGM; )

