/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#import "WXCanvasComponent.h"
#import "WXComponent_internal.h"
#import "WXUtility.h"
#import "WXConvert.h"
#import <Foundation/Foundation.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>


@interface WXCanvasComponent()
@property (nonatomic, strong) GLKView *glkview;
@property (nonatomic, strong) NSMutableDictionary *cacheMap;
@property (nonatomic, strong) NSMutableArray *drawActionList;
@property (nonatomic, strong) GLKBaseEffect *effect;
@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic, assign) NSInteger fps;
@property (nonatomic, strong) WXCanvasModule *canvasModule;
@property (nonatomic, assign) GLKVector4 curFillColor;
@property (nonatomic, assign) GLKVector4 curStrokeColor;
@property (nonatomic, assign) GLfloat curLineWidth;
@property (nonatomic, assign) GLfloat curGlobalAlpha;
@end


@implementation WXCanvasComponent

- (instancetype)initWithRef:(NSString *)ref
                       type:(NSString *)type
                     styles:(NSDictionary *)styles
                 attributes:(NSDictionary *)attributes
                     events:(NSArray *)events
               weexInstance:(WXSDKInstance *)weexInstance
{
    if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
        _fps = [WXConvert NSInteger:attributes[@"fps"]];
        if (!_fps) {
            _fps = 30;
        }
    }
    return self;
}


- (UIView *)loadView
{
    _glkview = [[GLKView alloc] init];
    EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    _glkview.context = context;
    _glkview.delegate = self;
    _glkview.enableSetNeedsDisplay = NO;
    _cacheMap = [NSMutableDictionary new];
    return _glkview;
}

- (void) viewDidLoad
{
    [super viewDidLoad];
    _drawActionList = [[NSMutableArray alloc] init];
    _effect = [[GLKBaseEffect alloc] init];
    CGSize size = _glkview.frame.size;
    _effect.transform.projectionMatrix = GLKMatrix4MakeOrtho(0, size.width, 0, size.height, -1024, 1024);
    _effect.transform.modelviewMatrix = GLKMatrix4Multiply(GLKMatrix4MakeTranslation(0, size.height, 0), GLKMatrix4MakeScale(1, -1, 1));
    _curStrokeColor = GLKVector4Make(1, 1, 1, 1);
    _curFillColor = GLKVector4Make(1, 1, 1, 1);
    _curGlobalAlpha = 1;
    _curLineWidth = 1;
}

- (void) viewDidUnload
{
    [_displayLink invalidate];
    _displayLink = nil;
    [_drawActionList removeAllObjects];
    _drawActionList = nil;
    _effect = nil;
    _canvasModule = nil;
    [_cacheMap removeAllObjects];
    _cacheMap = nil;
    [super viewDidUnload];
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    NSInteger count = [_drawActionList count];
    for (NSInteger i = 0; i < count; i++) {
        NSArray *action = (NSArray *)_drawActionList[i];
        NSInteger paramsCount = [action count];
        SEL method;
        if (paramsCount == 1) {
            method = NSSelectorFromString(action[0]);
        } else {
            method = NSSelectorFromString([action[0] stringByAppendingString:@":"]);
        }
        if (![self respondsToSelector:method]) {
            continue;
        }

        id params = nil;
        if (paramsCount > 1) {
            params = action[1];
        }
        [self performSelectorOnMainThread:method withObject:params waitUntilDone:YES];
    }

    [_drawActionList removeAllObjects];
}

// [
//      [setFillStyle, ["black"]],
//      [fillRect, [0, 0, 750, 750]],
//      [drawImages, [imgURL, [[sx, sy, sw, sh, dx, dy, dw, dh], [sx, sy, sw, sh, dx, dy, dw, dh]]]],
// ]
- (void) addDrawActions:(NSArray *)actions canvasModule:(WXCanvasModule*)canvasModule
{
    [_drawActionList removeAllObjects];
    [_drawActionList addObjectsFromArray:actions];
    _canvasModule = canvasModule;
    [_glkview display];
}


-(GLKTextureInfo *) getTexture:(NSString *)imageURL
{
    NSString *key = [NSString stringWithFormat:@"texture~%@", imageURL];
    if ([_cacheMap objectForKey:key]) {
        return (GLKTextureInfo *)[_cacheMap objectForKey:key];
    }

    // Image can cache by weexModule, so use it to get the UIImage
    UIImage *image = [_canvasModule getImage:imageURL];
    NSError *error;
    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
                                                        forKey:GLKTextureLoaderApplyPremultiplication];
    GLKTextureInfo *texture = [GLKTextureLoader textureWithCGImage:image.CGImage options:options error:&error];

    if (texture != nil) {
        [_cacheMap setObject:texture forKey:key];
    }

    return texture;
}

-(void) handleDisplayLink
{
    [self fireEvent:@"tick" params:nil];
}

- (void)addEvent:(NSString *)eventName
{
    if ([eventName isEqualToString:@"tick"]) {
        _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink)];
        float i = 60.0 / _fps;
        _displayLink.frameInterval = i;
        [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    }
}


// OpenGL ES methods map
#define WX_CANVAS_PIXEL(name, index) WXPixelType name = [WXConvert WXPixelType:params[index] scaleFactor:self.weexInstance.pixelScaleFactor];
#define WX_CANVAS_CGFLOAT(name, index) CGFloat name = [WXConvert CGFloat:params[index]];
#define WX_CANVAS_PARAMS_CHECK(num) if ([params count] < num) return;


// [imageURL, [[sx, sy, sw, sh, dx, dy, dw, dh], [sx, sy, sw, sh, dx, dy, dw, dh, m00, m01, m02, m10, m11, m12, m20, m21, m22]]]
- (void) drawImages:(NSArray *)params
{
    WX_CANVAS_PARAMS_CHECK(2);
    GLKTextureInfo *textureInfo = [self getTexture:[WXConvert NSString:params[0]]];
    CGFloat textureWidth = textureInfo.width;
    CGFloat textureHeight = textureInfo.height;

    NSArray *drawParams = (NSArray *)params[1];
    const GLint count = (GLint)[drawParams count] * 4;
    GLKVector3 geometrys[count];
    GLKVector3 textures[count];

    const GLint indexLen = (GLint)drawParams.count * 6;
    GLuint indices[indexLen];

    for (GLint i = 0; i < drawParams.count; i++) {
        NSArray *curParams = (NSArray *)drawParams[i];
        if (curParams.count < 8) {
            continue;
        }

        CGFloat sx = [WXConvert CGFloat:curParams[0]];
        CGFloat sy = [WXConvert CGFloat:curParams[1]];
        CGFloat sw = [WXConvert CGFloat:curParams[2]];
        CGFloat sh = [WXConvert CGFloat:curParams[3]];
        CGFloat dx = [WXConvert WXPixelType:curParams[4] scaleFactor:self.weexInstance.pixelScaleFactor];
        CGFloat dy = [WXConvert WXPixelType:curParams[5] scaleFactor:self.weexInstance.pixelScaleFactor];
        CGFloat dw = [WXConvert WXPixelType:curParams[6] scaleFactor:self.weexInstance.pixelScaleFactor];
        CGFloat dh = [WXConvert WXPixelType:curParams[7] scaleFactor:self.weexInstance.pixelScaleFactor];

        geometrys[i * 4] = GLKVector3Make(dx, dh + dy, 1);
        geometrys[i * 4 + 1] = GLKVector3Make(dw + dx, dh + dy, 1);
        geometrys[i * 4 + 2] = GLKVector3Make(dx, dy, 1);
        geometrys[i * 4 + 3] = GLKVector3Make(dw + dx, dy, 1);

        if (curParams.count == 17) {
            // If the length of curParams is 17, the tail of curParams is the transform matrix of this draw
            // m00, m01, m02, m10, m11, m12, m20, m21, m22
            GLKMatrix3 matrix = GLKMatrix3Make(
                                               [WXConvert CGFloat:curParams[8]],
                                               [WXConvert CGFloat:curParams[9]],
                                               [WXConvert CGFloat:curParams[10]],
                                               [WXConvert CGFloat:curParams[11]],
                                               [WXConvert CGFloat:curParams[12]],
                                               [WXConvert CGFloat:curParams[13]],
                                               [WXConvert CGFloat:curParams[14]],
                                               [WXConvert CGFloat:curParams[15]],
                                               [WXConvert CGFloat:curParams[16]]
            );
            // Because the params are base on 750, so we should make scale for the transform matrix
            matrix = GLKMatrix3Scale(matrix, 1, 1, self.weexInstance.pixelScaleFactor);
            geometrys[i * 4] = GLKMatrix3MultiplyVector3(matrix, geometrys[i * 4]);
            geometrys[i * 4 + 1] = GLKMatrix3MultiplyVector3(matrix, geometrys[i * 4 + 1]);
            geometrys[i * 4 + 2] = GLKMatrix3MultiplyVector3(matrix, geometrys[i * 4 + 2]);
            geometrys[i * 4 + 3] = GLKMatrix3MultiplyVector3(matrix, geometrys[i * 4 + 3]);
        }

        textures[i * 4] = GLKVector3Make(sx / textureWidth, (sy + sh) / textureHeight, 1);
        textures[i * 4 + 1] = GLKVector3Make((sx + sw) / textureWidth, (sy + sh) / textureHeight, 1);
        textures[i * 4 + 2] = GLKVector3Make(sx / textureWidth, sy / textureHeight, 1);
        textures[i * 4 + 3] = GLKVector3Make((sx + sw) / textureWidth, sy / textureHeight, 1);

        // two triangles 0,1,2 and 1,2,3 make a rectangle
        indices[i * 6] = i * 4;
        indices[i * 6 + 1] = i * 4 + 1;
        indices[i * 6 + 2] = i * 4 + 2;
        indices[i * 6 + 3] = i * 4 + 1;
        indices[i * 6 + 4] = i * 4 + 2;
        indices[i * 6 + 5] = i * 4 + 3;
    }

    glEnable(GL_BLEND);
    if (_curGlobalAlpha != 1) {
        glBlendColor(1, 1, 1, _curGlobalAlpha);
        glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE);
    } else {
        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    }

    _effect.useConstantColor = GL_FALSE;
    _effect.texture2d0.enabled = YES;
    _effect.texture2d0.name = textureInfo.name;
    [_effect prepareToDraw];

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, &geometrys);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 3, GL_FLOAT, GL_FALSE, 0, &textures);

    glDrawElements(GL_TRIANGLES, indexLen, GL_UNSIGNED_INT, indices);
}

- (void) setGlobalAlpha:(NSArray *)params
{
    WX_CANVAS_PARAMS_CHECK(1);
    _curGlobalAlpha = [WXConvert CGFloat:params[0]];
}


// use rgba(0, 0, 0, 0) to fill the rect
- (void) clearRect:(NSArray *)params
{
    WX_CANVAS_PARAMS_CHECK(4);
    WX_CANVAS_PIXEL(x, 0)
    WX_CANVAS_PIXEL(y, 1)
    WX_CANVAS_PIXEL(w, 2)
    WX_CANVAS_PIXEL(h, 3)

    _effect.useConstantColor = GL_TRUE;
    _effect.constantColor = GLKVector4Make(0, 0, 0, 0);
    _effect.texture2d0.enabled = NO;
    [_effect prepareToDraw];
    glBlendFunc(GL_ONE, GL_ZERO);

    glEnableVertexAttribArray(GLKVertexAttribPosition);

    GLfloat points[] = {
        x, y,
        x, y + h,
        x + w, y,
        x + w, y + h
    };

    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, &points);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

- (void) setStrokeStyle:(NSArray *)params
{
    WX_CANVAS_PARAMS_CHECK(1);
    UIColor *color = [WXConvert UIColor:params[0]];
    CGFloat red = 0.0, green = 0.0, blue = 0.0, alpha =0.0;
    [color getRed:&red green:&green blue:&blue alpha:&alpha];
    _curStrokeColor = GLKVector4Make(red, green, blue, alpha);
}

- (void) setLineWidth:(NSArray *)params
{
    WX_CANVAS_PARAMS_CHECK(1);
    _curLineWidth = [WXConvert WXPixelType:params[0] scaleFactor:self.weexInstance.pixelScaleFactor];
}

// ["M", 0, 0, "L", 100, 100, "L", 0, 100, "L", 0, 0] it made a triangle
- (void) strokeLines:(NSArray *)params
{
    WX_CANVAS_PARAMS_CHECK(1);
    const NSInteger pointsCount = floor([params count] / 3);
    GLKVector2 points[pointsCount];
    GLint indices[pointsCount * 2];
    GLint pointIndex = 0;
    GLint lineIndex = 0;
    BOOL isLastMove = YES;

    for (GLint i = 0; i < params.count; i += 3) {
        NSString *type = [WXConvert NSString:params[i]];
        points[pointIndex] = GLKVector2Make([WXConvert WXPixelType:params[i + 1] scaleFactor:self.weexInstance.pixelScaleFactor], [WXConvert WXPixelType:params[i + 2] scaleFactor:self.weexInstance.pixelScaleFactor]);

        if ([type isEqualToString:@"L"]) {
            if (isLastMove) {
                indices[lineIndex++] = pointIndex;
                if (lineIndex > 1) {
                    isLastMove = NO;
                }
            } else {
                indices[lineIndex] = indices[lineIndex - 1];
                lineIndex += 1;
                indices[lineIndex++] = pointIndex;
            }
        } else if (isLastMove && lineIndex > 0) {
            isLastMove = YES;
            indices[lineIndex - 1] = pointIndex;
        } else {
            isLastMove = YES;
            indices[lineIndex++] = pointIndex;
        }

        pointIndex += 1;
    }

    _effect.useConstantColor = GL_TRUE;
    _effect.constantColor = _curStrokeColor;
    _effect.texture2d0.enabled = NO;
    [_effect prepareToDraw];
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnableVertexAttribArray(GLKVertexAttribPosition);

    glLineWidth(_curLineWidth);

    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, &points);
    glDrawElements(GL_LINES, lineIndex, GL_UNSIGNED_INT, indices);
}

- (void) strokeRect:(NSArray *)params
{
    WX_CANVAS_PARAMS_CHECK(4);
    WX_CANVAS_PIXEL(x, 0)
    WX_CANVAS_PIXEL(y, 1)
    WX_CANVAS_PIXEL(w, 2)
    WX_CANVAS_PIXEL(h, 3)

    _effect.useConstantColor = GL_TRUE;
    _effect.constantColor = _curStrokeColor;
    _effect.texture2d0.enabled = NO;
    [_effect prepareToDraw];
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnableVertexAttribArray(GLKVertexAttribPosition);

    GLfloat points[] = {
        x, y,
        x, y + h,
        x + w, y + h,
        x + w, y,
        x, y
    };
    glLineWidth(_curLineWidth);

    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, &points);
    glDrawArrays(GL_LINE_STRIP, 0, 5);
}

// only support color, such as red, rgb(100, 100, 100), rgba(0, 0, 0, 1), #cccccc
-(void) setFillStyle:(NSArray *)params
{
    WX_CANVAS_PARAMS_CHECK(1);
    UIColor *color = [WXConvert UIColor:params[0]];
    CGFloat red = 0.0, green = 0.0, blue = 0.0, alpha =0.0;
    [color getRed:&red green:&green blue:&blue alpha:&alpha];
    _curFillColor = GLKVector4Make(red, green, blue, alpha);
}

- (void) fillRect:(NSArray *)params
{
    WX_CANVAS_PARAMS_CHECK(4);
    WX_CANVAS_PIXEL(x, 0)
    WX_CANVAS_PIXEL(y, 1)
    WX_CANVAS_PIXEL(w, 2)
    WX_CANVAS_PIXEL(h, 3)

    _effect.useConstantColor = GL_TRUE;
    _effect.constantColor = _curFillColor;
    _effect.texture2d0.enabled = NO;
    [_effect prepareToDraw];
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnableVertexAttribArray(GLKVertexAttribPosition);

    GLfloat points[] = {
        x, y,
        x, y + h,
        x + w, y,
        x + w, y + h
    };

    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, &points);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

@end
