/*
 ** Copyright 2011, The Android Open Source Project
 **
 ** 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.
 */

package com.android.glesv2debugger;

import com.android.glesv2debugger.DebuggerMessage.Message;
import com.android.glesv2debugger.DebuggerMessage.Message.Function;
import com.android.glesv2debugger.DebuggerMessage.Message.Type;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ExtendedModifyEvent;
import org.eclipse.swt.custom.ExtendedModifyListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class ShaderEditor extends Composite implements SelectionListener, ExtendedModifyListener,
        ProcessMessage {
    SampleView sampleView;

    ToolBar toolbar;
    ToolItem uploadShader, restoreShader, currentPrograms;
    List list;
    StyledText styledText;

    GLShader current;

    ArrayList<GLShader> shadersToUpload = new ArrayList<GLShader>();

    ShaderEditor(SampleView sampleView, Composite parent) {
        super(parent, 0);
        this.sampleView = sampleView;

        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 1;
        this.setLayout(gridLayout);

        toolbar = new ToolBar(this, SWT.BORDER);

        uploadShader = new ToolItem(toolbar, SWT.PUSH);
        uploadShader.setText("Upload Shader");
        uploadShader.addSelectionListener(this);

        restoreShader = new ToolItem(toolbar, SWT.PUSH);
        restoreShader.setText("Original Shader");
        restoreShader.addSelectionListener(this);

        currentPrograms = new ToolItem(toolbar, SWT.PUSH);
        currentPrograms.setText("Current Programs: ");

        list = new List(this, SWT.V_SCROLL);
        list.setFont(new Font(parent.getDisplay(), "Courier", 10, 0));
        list.addSelectionListener(this);
        GridData gridData = new GridData();
        gridData.horizontalAlignment = SWT.FILL;
        gridData.grabExcessHorizontalSpace = true;
        gridData.verticalAlignment = SWT.FILL;
        gridData.grabExcessVerticalSpace = true;
        list.setLayoutData(gridData);

        styledText = new StyledText(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI);
        gridData = new GridData();
        gridData.horizontalAlignment = SWT.FILL;
        gridData.grabExcessHorizontalSpace = true;
        gridData.verticalAlignment = SWT.FILL;
        gridData.grabExcessVerticalSpace = true;
        gridData.verticalSpan = 2;
        styledText.setLayoutData(gridData);
        styledText.addExtendedModifyListener(this);
    }

    public void updateUI() {
        list.removeAll();
        String progs = "Current Programs: ";
        for (int j = 0; j < sampleView.debugContexts.size(); j++) {
            final Context context = sampleView.debugContexts.valueAt(j).currentContext;

            if (context.serverShader.current != null) {
                progs += context.serverShader.current.name + "(0x";
                progs += Integer.toHexString(context.contextId) + ") ";
            }
            for (int i = 0; i < context.serverShader.shaders.size(); i++) {
                GLShader shader = context.serverShader.shaders.valueAt(i);
                StringBuilder builder = new StringBuilder();
                builder.append(String.format("%08X", context.contextId));
                builder.append(' ');
                builder.append(shader.type);
                while (builder.length() < 30)
                    builder.append(" ");
                builder.append(shader.name);
                while (builder.length() < 40)
                    builder.append(" ");
                builder.append(" : ");
                for (Context ctx : context.shares) {
                    builder.append(String.format("%08X", ctx.contextId));
                    builder.append(' ');
                }
                builder.append(": ");
                for (int program : shader.programs) {
                    builder.append(program);
                    builder.append(" ");
                }
                list.add(builder.toString());
            }

        }

        currentPrograms.setText(progs);
        toolbar.redraw();
        toolbar.pack(true);
        toolbar.update();
    }

    void uploadShader() {
        current.source = styledText.getText();

        try {
            File file = File.createTempFile("shader",
                    current.type == GLEnum.GL_VERTEX_SHADER ? ".vert" : ".frag");
            FileWriter fileWriter = new FileWriter(file, false);
            fileWriter.write(current.source);
            fileWriter.close();

            ProcessBuilder processBuilder = new ProcessBuilder(
                    "./glsl_compiler", "--glsl-es", file.getAbsolutePath());
            final Process process = processBuilder.start();
            InputStream is = process.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line;
            String infolog = "";

            styledText.setLineBackground(0, styledText.getLineCount(), null);

            while ((line = br.readLine()) != null) {
                infolog += line;
                if (!line.startsWith("0:"))
                    continue;
                String[] details = line.split(":|\\(|\\)");
                final int ln = Integer.parseInt(details[1]);
                if (ln > 0) // usually line 0 means errors other than syntax
                    styledText.setLineBackground(ln - 1, 1,
                            new Color(Display.getCurrent(), 255, 230, 230));
            }
            file.delete();
            if (infolog.length() > 0) {
                if (!MessageDialog.openConfirm(getShell(),
                        "Shader Syntax Error, Continue?", infolog))
                    return;
            }
        } catch (IOException e) {
            sampleView.showError(e);
        }

        // add the initial command, which when read by server will set
        // expectResponse for the message loop and go into message exchange
        synchronized (shadersToUpload) {
            for (GLShader shader : shadersToUpload) {
                if (shader.context.context.contextId != current.context.context.contextId)
                    continue;
                MessageDialog.openWarning(this.getShell(), "Context 0x" +
                        Integer.toHexString(current.context.context.contextId),
                        "Previous shader upload not complete, try again");
                return;
            }
            shadersToUpload.add(current);
            final int contextId = current.context.context.contextId;
            Message.Builder builder = getBuilder(contextId);
            MessageParserEx.instance.parse(builder,
                    String.format("glShaderSource(%d,1,\"%s\",0)", current.name, current.source));
            sampleView.messageQueue.addCommand(builder.build());
        }
    }

    Message.Builder getBuilder(int contextId) {
        Message.Builder builder = Message.newBuilder();
        builder.setContextId(contextId);
        builder.setType(Type.Response);
        builder.setExpectResponse(true);
        return builder;
    }

    Message exchangeMessage(final int contextId, final MessageQueue queue,
            String format, Object... args) throws IOException {
        Message.Builder builder = getBuilder(contextId);
        MessageParserEx.instance.parse(builder, String.format(format, args));
        final Function function = builder.getFunction();
        queue.sendMessage(builder.build());
        final Message msg = queue.receiveMessage(contextId);
        assert msg.getContextId() == contextId;
        assert msg.getType() == Type.AfterGeneratedCall;
        assert msg.getFunction() == function;
        return msg;
    }

    // this is called from network thread
    public boolean processMessage(final MessageQueue queue, final Message msg)
            throws IOException {
        GLShader shader = null;
        final int contextId = msg.getContextId();
        synchronized (shadersToUpload) {
            if (shadersToUpload.size() == 0)
                return false;
            boolean matchingContext = false;
            for (int i = 0; i < shadersToUpload.size(); i++) {
                shader = shadersToUpload.get(i);
                for (Context ctx : shader.context.context.shares)
                    if (ctx.contextId == contextId) {
                        matchingContext = true;
                        break;
                    }
                if (matchingContext) {
                    shadersToUpload.remove(i);
                    break;
                }
            }
            if (!matchingContext)
                return false;
        }

        // glShaderSource was already sent to trigger set expectResponse
        assert msg.getType() == Type.AfterGeneratedCall;
        assert msg.getFunction() == Function.glShaderSource;

        exchangeMessage(contextId, queue, "glCompileShader(%d)", shader.name);

        // the 0, "" and {0} are dummies for the parser
        Message rcv = exchangeMessage(contextId, queue,
                "glGetShaderiv(%d, GL_COMPILE_STATUS, {0})", shader.name);
        assert rcv.hasData();
        if (rcv.getData().asReadOnlyByteBuffer().getInt() == 0) {
            // compile failed
            rcv = exchangeMessage(contextId, queue,
                    "glGetShaderInfoLog(%d, 0, 0, \"\")", shader.name);
            final String title = String.format("Shader %d in 0x%s failed to compile",
                    shader.name, Integer.toHexString(shader.context.context.contextId));
            final String message = rcv.getData().toStringUtf8();
            sampleView.getSite().getShell().getDisplay().syncExec(new Runnable() {
                @Override
                public void run()
                {
                    MessageDialog.openWarning(getShell(), title, message);
                }
            });
        } else
            for (int programName : shader.programs) {
                GLProgram program = shader.context.getProgram(programName);
                exchangeMessage(contextId, queue, "glLinkProgram(%d)", program.name);
                rcv = exchangeMessage(contextId, queue,
                        "glGetProgramiv(%d, GL_LINK_STATUS, {0})", program.name);
                assert rcv.hasData();
                if (rcv.getData().asReadOnlyByteBuffer().getInt() != 0)
                    continue;
                // link failed
                rcv = exchangeMessage(contextId, queue,
                            "glGetProgramInfoLog(%d, 0, 0, \"\")", program.name);
                final String title = String.format("Program %d in 0x%s failed to link",
                        program.name, Integer.toHexString(program.context.context.contextId));
                final String message = rcv.getData().toStringUtf8();
                sampleView.getSite().getShell().getDisplay().syncExec(new Runnable() {
                    @Override
                    public void run()
                    {
                        MessageDialog.openWarning(getShell(), title, message);
                    }
                });
                // break;
            }

        // TODO: add to upload results if failed

        Message.Builder builder = getBuilder(contextId);
        builder.setExpectResponse(false);
        if (queue.getPartialMessage(contextId) != null)
            // the glShaderSource interrupted a BeforeCall, so continue
            builder.setFunction(Function.CONTINUE);
        else
            builder.setFunction(Function.SKIP);
        queue.sendMessage(builder.build());

        return true;
    }

    @Override
    public void widgetSelected(SelectionEvent e) {
        if (e.getSource() == uploadShader && null != current) {
            uploadShader();
            return;
        } else if (e.getSource() == restoreShader && null != current) {
            current.source = styledText.getText();
            styledText.setText(current.originalSource);
            return;
        }

        if (list.getSelectionCount() < 1)
            return;
        if (null != current && !current.source.equals(styledText.getText())) {
            String[] btns = {
                    "&Upload", "&Save", "&Discard"
            };
            MessageDialog dialog = new MessageDialog(this.getShell(), "Shader Edited",
                    null, "Shader source has been edited", MessageDialog.QUESTION, btns, 0);
            int rc = dialog.open();
            if (rc == SWT.DEFAULT || rc == 0)
                uploadShader();
            else if (rc == 1)
                current.source = styledText.getText();
            // else if (rc == 2) do nothing; selection is changing
        }
        String[] details = list.getSelection()[0].split("\\s+");
        final int contextId = Integer.parseInt(details[0], 16);
        int name = Integer.parseInt(details[2]);
        current = sampleView.debugContexts.get(contextId).currentContext.serverShader.shaders
                .get(name);
        styledText.setText(current.source);
    }

    @Override
    public void widgetDefaultSelected(SelectionEvent e) {
        widgetSelected(e);
    }

    @Override
    public void modifyText(ExtendedModifyEvent event) {
        final String[] keywords = {
                "gl_Position", "gl_FragColor"
        };
        // FIXME: proper scanner for syntax highlighting
        String text = styledText.getText();
        int start = event.start;
        int end = event.start + event.length;
        start -= 20; // deleting chars from keyword causes rescan
        end += 20;
        if (start < 0)
            start = 0;
        if (end > text.length())
            end = text.length();
        if (null != styledText.getStyleRangeAtOffset(event.start)) {
            StyleRange clearStyleRange = new StyleRange();
            clearStyleRange.start = start;
            clearStyleRange.length = end - start;
            clearStyleRange.foreground = event.display.getSystemColor(SWT.COLOR_BLACK);
            styledText.setStyleRange(clearStyleRange);
        }

        while (start < end) {
            for (final String keyword : keywords) {
                if (!text.substring(start).startsWith(keyword))
                    continue;
                if (start > 0) {
                    final char before = text.charAt(start - 1);
                    if (Character.isLetterOrDigit(before))
                        continue;
                    else if (before == '_')
                        continue;
                }
                if (start + keyword.length() < text.length()) {
                    final char after = text.charAt(start + keyword.length());
                    if (Character.isLetterOrDigit(after))
                        continue;
                    else if (after == '_')
                        continue;
                }
                StyleRange style1 = new StyleRange();
                style1.start = start;
                style1.length = keyword.length();
                style1.foreground = event.display.getSystemColor(SWT.COLOR_BLUE);
                styledText.setStyleRange(style1);
            }
            start++;
        }
    }
}
