/*
 * Copyright (c) 2011, Oracle  and/or its affiliates. All rights reserved.
 *
 * Use is subject to license terms.
 */

package com.sun.javafx.tk.quantum;

import com.sun.glass.ui.View;
import com.sun.glass.ui.Window;
import com.sun.javafx.geom.CameraImpl;
import com.sun.prism.Graphics;
import com.sun.prism.GraphicsPipeline;
import com.sun.prism.camera.PrismCameraImpl;
import com.sun.prism.impl.PrismSettings;
import com.sun.prism.paint.Color;
import com.sun.prism.paint.Paint;


/**
 * @author Morris Meyer
 */
public class ViewPainter extends AbstractPainter {

    private WindowStage         windowStage;
    private Window              window;

    protected View              view;  
    protected PrismPen          pen;

    // Pen dimensions. Pen width and height are checked on every repaint
    // to match its scene width/height. If any difference is found, the
    // pen surface (Presentable or RTTexture) is recreated.
    protected int               penWidth = -1;
    protected int               penHeight = -1;
    protected int               viewWidth;
    protected int               viewHeight;
    
    protected boolean           valid;

    protected ViewPainter(GlassScene gs, PrismPen pp) {
        super(gs);
        
        pen = pp;
    }
        
    @Override protected boolean validateStageGraphics() {
        valid = super.validateStageGraphics();
        
        if (!valid) {
            return false;
        }

        synchronized (this) {
            ViewScene vs = (ViewScene)scene;
            view = vs.getPlatformView();
            
            if (view == null) {
                return false;
            }
            if (view.isClosed()) {
                return false;
            }
            
            viewWidth = view.getWidth();
            viewHeight = view.getHeight();

            if ((viewWidth <= 0) || (viewHeight <= 0)) {
                return false;
            }
            setPaintBounds(viewWidth, viewHeight);
        }
        
        windowStage = (WindowStage)scene.glassStage;
        window      = windowStage.platformWindow;

        if (window == null) {
            return false;
        }
        
        if (factory == null) {
            try {
                view.lock();
                factory = GraphicsPipeline.getDefaultResourceFactory();
            } finally {
                /* 
                 * Don't flush to the screen if there was a failure 
                 * creating the graphics factory 
                 */
                view.unlock(factory != null);
            }
            return ((factory != null) && factory.isDeviceReady());
        }
        return (window.isVisible() && !window.isMinimized()
                                   && factory.isDeviceReady());
    }
    
    @Override protected void doPaint(Graphics g) {
        if (PrismSettings.showDirtyRegions) {
            g.setClipRect(null);
        }
        scene.clearEntireSceneDirty();
        g.setDepthBuffer(pen.getDepthBuffer());
        Color clearColor = pen.getClearColor();
        if (clearColor != null) {
            g.clear(clearColor);
        }
        Paint curPaint = pen.getCurrentPaint();
        if (curPaint != null) {
            if (curPaint.getType() != com.sun.prism.paint.Paint.Type.COLOR) {
                g.getRenderTarget().setOpaque(curPaint.isOpaque());
            }
            g.setPaint(curPaint);
            g.fillQuad(0, 0, width, height);
        }
        g.setCamera((PrismCameraImpl)pen.getCamera());        
        root.render(g);
    }
    
    @Override protected CameraImpl getCamera() {
        if (pen != null) {
            return pen.getCamera();
        }
        return null;
    }

}