/*
 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
 */

package com.sun.rain.graphics;

import com.sun.rain.shapes.Shape;

import com.sun.glass.ui.Pen;
import com.sun.glass.ui.View;

import java.nio.ByteBuffer;

import java.util.Map;
import java.util.HashMap;

public abstract class Graphics2D extends Pen
{
    static native void _initIDs();
    static
    {
        System.loadLibrary("rain");

        // TODO: get rid of _initIDs
        _initIDs();
    }

    // Native Graphics2D pointer
    private long ptr = 0;

    static final private Map capabilities = new HashMap();
    static
    {
        Graphics2D.capabilities.put(View.Capability.k3dKey, new Boolean(false));
    }

    native long _createGraphics();
    public Graphics2D()
    {
        this.ptr = _createGraphics();
    }

    public Map getCapabilities()
    {
        return Graphics2D.capabilities;
    }

    native void _setColor(long ptr, Color color);
    public void set(Color color)
    {
        if (color != null)
        {
            _setColor(this.ptr, color);
        }
    }

    native void _setFont(long ptr, Font font);
    public void set(Font font)
    {
        if (font != null)
        {
            _setFont(this.ptr, font);
        }
    }

    native void _drawString(long ptr, String string, float x, float y);
    public void draw(String string, float x, float y)
    {
        if (string != null)
        {
            _drawString(this.ptr, string, x, y);
        }
    }

    native void _fillRect(long ptr, float x, float y, float width, float height);
    public void fillRect(float x, float y, float width, float height)
    {
        _fillRect(this.ptr, x, y, width, height);
    }

    native void _fillEllipse(long ptr, float x, float y, float width, float height);
    public void fillEllipse(float x, float y, float width, float height)
    {
        _fillEllipse(this.ptr, x, y, width, height);
    }

    native void _fillShape(long ptr, Shape shape, ByteBuffer buffer, float x, float y);
    public void fill(Shape shape)
    {
        fill(shape, 0.0f, 0.0f);
    }
    public void fill(Shape shape, float x, float y)
    {
        if (shape != null)
        {
            _fillShape(this.ptr, shape, shape.compile(), x, y);
        }
    }

    native void _drawImage(long ptr, Image image, float x, float y, float width, float height);
    public void draw(Image image)
    {
        draw(image, 0.0f, 0.0f);
    }
    public void draw(Image image, float x, float y)
    {
        draw(image, x, y, image.getWidth(), image.getHeight());
    }
    public void draw(Image image, float x, float y, float width, float height)
    {
        if (image != null)
        {
            _drawImage(this.ptr, image, x, y, image.getWidth(), image.getHeight());
        }
    }

    native void _translate(long ptr, float x, float y);
    public void translate(float x, float y)
    {
         _translate(this.ptr, x, y);
    }

    native void _scale(long ptr, float x, float y);
    public void scale(float x, float y)
    {
         _scale(this.ptr, x, y);
    }

    native void _rotate(long ptr, float a);
    public void rotate(float a)
    {
         _rotate(this.ptr, a);
    }

    native void _pushCTM(long ptr);
    public void pushCTM()
    {
        _pushCTM(this.ptr);
    }

    native void _popCTM(long ptr);
    public void popCTM()
    {
        _popCTM(this.ptr);
    }

    native void _clip(long ptr, float x, float y, float width, float height);
    public void clip(float x, float y, float width, float height)
    {
        _clip(this.ptr, x, y, width, height);
    }

    native void _pushClip(long ptr);
    public void pushClip()
    {
        _pushClip(this.ptr);
    }

    native void _popClip(long ptr);
    public void popClip()
    {
        _popClip(this.ptr);
    }

    public void push()
    {
        pushCTM();
        pushClip();
    }

    public void pop()
    {
        popCTM();
        popClip();
    }
    
    native void _begin(long ptr, long viewPtr);
    native void _end(long ptr);
    
    @Override
    public void begin()
    {
        if (getView() != null)
        {
            getView().lock();
            long viewPtr = getView().getNativeView();
            _begin(this.ptr, viewPtr);
        }
    }
    
    @Override
    public void end()
    {
        end(true);
    }
    public void end(boolean flush)
    {
        if (getView() != null)
        {
            _end(this.ptr);
            getView().unlock(flush);
        }
    }
}
