/*
 * Decompiled with CFR 0_132.
 */
package signals;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import main.ChronoPanel;

public abstract class Signals
implements Serializable {
    private static final long serialVersionUID = 1L;
    public static int leftSpace = 80;
    public static int Yspace = 20;
    public static int heightUnit = 25;
    private static int idBank = 0;
    public int id = -1;
    public int widthUnit = 20;
    public String name;
    public int setUpTime = 0;
    public boolean bus = false;
    public boolean clock = false;
    public boolean dependsOnClk = false;
    public float ratio = 1.0f;
    public int clockDomainId;
    public boolean selected_for_edit = false;
    public boolean clkToQdelay = false;
    public boolean displayRisingEdges = false;
    public boolean bold = false;
    public Color color = Color.black;
    public transient boolean selected = false;
    public int[] wave = new int[500];
    protected String[] busNames = new String[500];
    protected boolean[] busFill = new boolean[500];

    public abstract void generate(boolean var1);

    public static void resetIdBank() {
        idBank = 0;
    }

    public static void setIdBank(int id) {
        idBank = id;
    }

    protected void setId() {
        this.id = idBank++;
    }

    public void setWave(int x, boolean toggle) {
        int newValue = 0;
        if (this.clkToQdelay) {
            x += this.widthUnit / 2;
        }
        if (!this.clock) {
            int value = this.wave[(x - leftSpace) / this.widthUnit];
            if (value == 0) {
                newValue = 1;
            }
            if (value == 1) {
                newValue = 0;
            }
            int i = 0;
            do {
                this.wave[(x - Signals.leftSpace) / this.widthUnit + i] = newValue;
            } while ((x - leftSpace) / this.widthUnit + ++i < 500 && this.wave[(x - leftSpace) / this.widthUnit + i] == value && toggle);
            if (this.bus) {
                if (this.busNames[(x - leftSpace) / this.widthUnit] != null) {
                    this.setBusName(x, this.busNames[(x - leftSpace) / this.widthUnit]);
                }
                if (this.busFill[(x - leftSpace) / this.widthUnit]) {
                    this.setBusFill(x, false);
                }
                while ((x - leftSpace) / this.widthUnit + i < 500) {
                    if (this.wave[(x - leftSpace) / this.widthUnit + i] == 0) {
                        this.wave[(x - Signals.leftSpace) / this.widthUnit + i] = 1;
                    } else if (this.wave[(x - leftSpace) / this.widthUnit + i] == 1) {
                        this.wave[(x - Signals.leftSpace) / this.widthUnit + i] = 0;
                    }
                    ++i;
                }
            }
        }
    }

    public void setBusName(int x, String s) {
        int indice = (x - leftSpace) / this.widthUnit;
        int i = this.getFirstChange(x);
        while (i < this.getNextChange(indice)) {
            this.busNames[i] = null;
            ++i;
        }
        this.busNames[this.getFirstChange((int)x)] = s;
    }

    public void setBusFill(int x, boolean clean) {
        int indice = (x - leftSpace) / this.widthUnit;
        if (!clean) {
            boolean mem = this.busFill[this.getFirstChange(x)];
            int i = this.getFirstChange(x);
            while (i < this.getNextChange(indice)) {
                this.busFill[i] = false;
                ++i;
            }
            this.busFill[this.getFirstChange((int)x)] = !mem;
        } else {
            int i = this.getFirstChange(x);
            while (i < this.getNextChange(indice)) {
                this.busFill[i] = false;
                ++i;
            }
        }
    }

    public int getFirstChange(int x) {
        int indice = (x - leftSpace) / this.widthUnit;
        while (indice > 0 && this.wave[indice - 1] == this.wave[indice]) {
            --indice;
        }
        return indice;
    }

    public int getIndex(int x) {
        return (x - leftSpace) / this.widthUnit;
    }

    public int getNextChange(int offset) {
        int indice = offset;
        while (indice < 199 && this.wave[indice + 1] == this.wave[indice]) {
            ++indice;
        }
        return indice;
    }

    public int getLastDisplayed(int maxWidth) {
        int res = 0;
        int i = 0;
        while (i < 200) {
            if (leftSpace + (i + 1) * this.widthUnit < maxWidth - 10) {
                ++res;
            }
            ++i;
        }
        return leftSpace + res * this.widthUnit;
    }

    public void draw(Graphics g, ChronoPanel chrono, int nbr, int maxWidth) {
        Graphics2D g2 = (Graphics2D)g;
        float[] dash1 = new float[]{5.0f};
        float thickness = 1.0f;
        g.setFont(ChronoPanel.myFont);
        if (this.bold) {
            g.setFont(ChronoPanel.myBoldFont);
            thickness = 3.0f;
        }
        BasicStroke dashed = new BasicStroke(thickness, 0, 0, 10.0f, dash1, 0.0f);
        if (this.selected) {
            g.setColor(new Color(215, 215, 235));
            g.fillRect(0, nbr * (heightUnit + Yspace) + Yspace / 2, maxWidth - 15, heightUnit + Yspace);
        }
        g.setColor(this.color);
        g.translate(0, nbr * (heightUnit + Yspace) + Yspace);
        g.drawString(this.name, leftSpace - (ChronoPanel.metrics.stringWidth(this.name) + 8), heightUnit - 1);
        g.translate(leftSpace, 0);
        g2.setStroke(new BasicStroke(thickness));
        if (this.bus) {
            this.drawBusFillOptions(g, 0, maxWidth - 15 - leftSpace);
        }
        if (chrono != null && chrono.nbrTimeLapse > 0) {
            this.drawSignalsInInterval(g, 0, chrono.timeLapse[0][0]);
            this.drawSignalsInInterval(g, chrono.timeLapse[chrono.nbrTimeLapse - 1][3], maxWidth - 15 - leftSpace);
        } else {
            this.drawSignalsInInterval(g, 0, maxWidth - 15 - leftSpace);
        }
        if (chrono != null) {
            int i = 0;
            while (i < chrono.nbrTimeLapse) {
                int j = 0;
                while (j < 3) {
                    if (j == 0 || j == 2) {
                        g2.setStroke(dashed);
                        this.drawSignalsInInterval(g, chrono.timeLapse[i][j], chrono.timeLapse[i][j + 1]);
                        g2.setStroke(new BasicStroke(thickness));
                    }
                    ++j;
                }
                if (i < chrono.nbrTimeLapse - 1) {
                    this.drawSignalsInInterval(g, chrono.timeLapse[i][3], chrono.timeLapse[i + 1][0]);
                }
                ++i;
            }
        }
        g.translate(- leftSpace, 0);
        g2.setStroke(new BasicStroke());
        g.setFont(ChronoPanel.myFont);
        g.translate(0, - nbr * (heightUnit + Yspace) + Yspace);
    }

    public void drawSignalsInInterval(Graphics g, int min, int max) {
        Rectangle2D.Float drawArea = new Rectangle2D.Float(min, -1.0f, max - min, heightUnit + 3);
        int limit = max / this.widthUnit + 2;
        g.setClip(drawArea);
        if (this.bus) {
            g.translate((- this.setUpTime) / 2, 0);
        }
        if (this.clkToQdelay) {
            g.translate((- this.widthUnit) / 2, 0);
        }
        int i = 0;
        while (i < limit) {
            if (i > 0 && this.wave[i - 1] != this.wave[i]) {
                if (this.wave[i] == 0 || this.bus) {
                    g.drawLine(i * this.widthUnit, 0, i * this.widthUnit + this.setUpTime, heightUnit);
                }
                if (this.wave[i] == 1 || this.bus) {
                    g.drawLine(i * this.widthUnit, heightUnit, i * this.widthUnit + this.setUpTime, 0);
                }
            } else if (this.setUpTime > 0 || this.bus) {
                if (this.wave[i] == 0 || this.bus) {
                    g.drawLine(i * this.widthUnit, heightUnit, i * this.widthUnit + this.setUpTime - 1, heightUnit);
                }
                if (this.wave[i] == 1 || this.bus) {
                    g.drawLine(i * this.widthUnit, 0, i * this.widthUnit + this.setUpTime - 1, 0);
                }
            }
            if (this.wave[i] == 0 || this.bus) {
                g.drawLine(i * this.widthUnit + this.setUpTime, heightUnit, (i + 1) * this.widthUnit - 1, heightUnit);
            }
            if (this.wave[i] == 1 || this.bus) {
                g.drawLine(i * this.widthUnit + this.setUpTime, 0, (i + 1) * this.widthUnit - 1, 0);
            }
            ++i;
        }
        if (this.bus) {
            g.translate(this.setUpTime / 2, 0);
        }
        if (this.clkToQdelay) {
            g.translate(this.widthUnit / 2, 0);
        }
        g.setClip(null);
    }

    public void drawBusFillOptions(Graphics g, int min, int max) {
        Rectangle2D.Float drawArea = new Rectangle2D.Float(min, 0.0f, max - min, heightUnit + 1);
        g.setClip(drawArea);
        if (this.bus) {
            g.translate((- this.setUpTime) / 2, 0);
        }
        if (this.clkToQdelay) {
            g.translate((- this.widthUnit) / 2, 0);
        }
        int i = 0;
        while (i < 200) {
            int left = i * this.widthUnit + this.setUpTime;
            if (i == 0) {
                left = 0;
            }
            int endData = (this.getNextChange(i) + 1) * this.widthUnit;
            if (this.busFill[i]) {
                int j;
                g.setColor(new Color(Math.min(this.color.getRed() + 150, 255), Math.min(this.color.getGreen() + 150, 255), Math.min(this.color.getBlue() + 150, 255)));
                g.fillRect(left, 0, endData - left, heightUnit);
                int start = this.setUpTime / 2;
                if (left != 0 && this.setUpTime != 0) {
                    j = 0;
                    while (j < start) {
                        g.drawLine(left - start + j, heightUnit / 2 - j * heightUnit / (2 * start), left - start + j, heightUnit / 2 + j * heightUnit / (2 * start));
                        ++j;
                    }
                }
                if (endData != this.getLastDisplayed(max) && this.setUpTime != 0) {
                    j = start;
                    while (j >= 0) {
                        g.drawLine(endData + start - j, heightUnit / 2 - j * heightUnit / (2 * start), endData + start - j, heightUnit / 2 + j * heightUnit / (2 * start));
                        --j;
                    }
                }
                g.setColor(this.color);
            }
            if (this.busNames[i] != null) {
                endData = Math.min((this.getNextChange(i) + 1) * this.widthUnit, this.getLastDisplayed(max));
                g.drawString(this.busNames[i], (left + endData) / 2 - ChronoPanel.metrics.stringWidth(this.busNames[i]) / 2, heightUnit - 8);
            }
            ++i;
        }
        if (this.bus) {
            g.translate(this.setUpTime / 2, 0);
        }
        if (this.clkToQdelay) {
            g.translate(this.widthUnit / 2, 0);
        }
        g.setClip(null);
    }
}

