public MethodDescription(ADeconstructorDecl method)
        {
            Parser parser = new Parser(method);

            Start = parser.Start;
            End = parser.End;
            ReturnType = "void";
            Name = parser.Name;
            Formals = parser.Formals;
            Locals = parser.Locals;
            if (method.Parent() != null)
                method.Parent().RemoveChild(method);
            while (method.GetFormals().Count > 0)
                Decl.GetFormals().Add(method.GetFormals()[0]);
            Visibility = method.GetVisibilityModifier();
            Position = TextPoint.FromCompilerCoords(method.GetName());
        }
        public MethodDescription(AConstructorDecl method, string type)
        {
            Parser parser = new Parser(method);

            Start = parser.Start;
            End = parser.End;
            ReturnType = type;
            Name = parser.Name;
            Formals = parser.Formals;
            Locals = parser.Locals;
            if (method.Parent() != null)
                method.Parent().RemoveChild(method);
            Decl = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new ANamedType(new TIdentifier(type), null),
                                   new TIdentifier(""), new ArrayList(), method.GetBlock());
            while (method.GetFormals().Count > 0)
                Decl.GetFormals().Add(method.GetFormals()[0]);
            Visibility = method.GetVisibilityModifier();
            Position = TextPoint.FromCompilerCoords(method.GetName());
        }
        public MethodDescription(AMethodDecl method)
        {
            Parser parser = new Parser(method);

            Start = parser.Start;
            End = parser.End;
            ReturnType = parser.ReturnType;
            Name = parser.Name;
            Formals = parser.Formals;
            Locals = parser.Locals;
            if (method.Parent() != null)
                method.Parent().RemoveChild(method);
            IsDelegate = method.GetDelegate() != null;
            //if (!IsDelegate)
                Decl = method;
            IsStatic = method.GetStatic() != null;
            Visibility = method.GetVisibilityModifier();
            realType = (PType)method.GetReturnType().Clone();
            Position = TextPoint.FromCompilerCoords(method.GetName());
        }
        public void UndoInsert(TextPoint pos, string text)
        {
            string[] texts = text.Split('\n');
            int cLine = pos.Line;
            string endText = lines[pos.Line].Text.Substring(pos.Pos);
            if (pos.Pos < lines[pos.Line].Text.Length)
                lines[pos.Line].Text = lines[pos.Line].Text.Remove(pos.Pos);
            lines[pos.Line].Text += texts[0];
            lines[pos.Line].Invalidated = true;
            lines[pos.Line].edited = true;
            List<Line> editedLines = new List<Line>(){lines[pos.Line]};
            for (int i = 1; i < texts.Length; i++)
            {
                Line newLine = new Line(texts[i]);
                cLine++;
                lines.Insert(cLine, newLine);
                lines[cLine].Invalidated = true;
                lines[cLine].edited = true;
                editedLines.Add(newLine);
            }

            if (texts.Length > 1)
            {//We added a line - invalidate all following
                for (int i = cLine; i < lines.Count; i++)
                {
                    lines[i].Invalidated = true;
                }
            }

            caret.SetPosition(new TextPoint(cLine, lines[cLine].Text.Length), true);
            lines[cLine].Text += endText;
            ExtendedLines(editedLines);
            ShrunkLine(lines[pos.Line]);
            UpdateBlocks();
            TextEdited();
            CaretMoved();
            Invalidate();
            Form1.Form.suggestionBox.Hide();
        }
        public void ReplaceTextAt(TextPoint from, TextPoint to, string text)
        {
            string removedText = "";
            for (int line = from.Line; line <= to.Line; line++)
            {
                if (line == from.Line)
                {
                    if (line == to.Line)
                        removedText += lines[line].Text.Remove(0, from.Pos).Substring(0, to.Pos - from.Pos);
                    else
                        removedText += lines[line].Text.Remove(0, to.Pos) + "\n";
                }
                else
                {
                    if (line == to.Line)
                        removedText += lines[line].Text.Substring(0, to.Pos);
                    else
                        removedText += lines[line].Text + "\n";
                }
            }
            UndoSys.TextReplaced(removedText, text, this, new TextPoint(from.Line, from.Pos));

            lines[from.Line].Invalidated = true;
            lines[from.Line].edited = true;
            if (from.Line == to.Line)
                //Cut text between min and max
                lines[from.Line].Text = lines[from.Line].Text.Remove(from.Pos, to.Pos - from.Pos);
            else
                //Cut end of min line, and replace with end of max line
                lines[from.Line].Text = lines[from.Line].Text.Substring(0, from.Pos) + lines[to.Line].Text.Remove(0, to.Pos);
            //Cut lines between min and max
            while (from.Line < to.Line)
            {
                lines.RemoveAt(from.Line + 1);
                to.Line--;
            }

            //Insert text
            lines[from.Line].Text = lines[from.Line].Text.Insert(from.Pos, text);

            caret.SetPosition(new TextPoint(from.Line, from.Pos + text.Length), true);
            //Dont know if it is shrunk or not, so call both :)
            ExtendedLines(new List<Line>() { lines[from.Line] });
            ShrunkLine(lines[from.Line]);
            UpdateBlocks();
            TextEdited();
            CaretMoved();
            Invalidate();
        }
        public void InsertEvent(string name, bool jumpToIt)
        {
            //Look for method with signature
            //void <name>(int sender, <dialogname>* dialog);
            //If found, set caret to that place, if not - append it and set carret

            //Don't assume the code can compile
            string code = ActualCode;
            int lines = 0;
            foreach (char c in code)
            {
                if (c == '\n')
                    lines++;
            }
            TextPoint focusAt = new TextPoint(-1, -1);
            using (StringReader reader = new StringReader(code))
            {
                Lexer lexer = new Lexer(reader);
                List<Token> tokens = new List<Token>();
                Token token = null;
                while ((token = lexer.Next()) != null)
                {
                    if (token is EOF)
                        break;
                    if (token is TWhiteSpace || token is TTraditionalComment || token is TEndOfLineComment)
                        continue;
                    tokens.Add(token);
                }
                for (int i = 0; i < tokens.Count - 11; i++)
                {
                    token = tokens[i];
                    if (token is TVoid)
                    {
                        token = tokens[i + 1];
                        if (token is TIdentifier && token.Text == name && tokens[i + 2] is TLParen)
                        {
                            token = tokens[i + 3];
                            if (token is TIdentifier && token.Text == "int" &&
                                tokens[i + 4] is TIdentifier && tokens[i + 5] is TComma)
                            {
                                token = tokens[i + 6];
                                if (token is TIdentifier && token.Text == DialogIdentiferName &&
                                    tokens[i + 7] is TStar && tokens[i + 8] is TIdentifier &&
                                    tokens[i + 9] is TRParen && tokens[i + 10] is TLBrace)
                                {
                                    focusAt = TextPoint.FromCompilerCoords(tokens[i + 10]);
                                }
                            }

                        }
                    }
                }
            }

            if (focusAt.Line == -1)
            {//Didn't find it. Append it
                jumpToIt = true;//This should not be auto saved. Have to open it.
                string s = "\n\nvoid " + name + "(int sender, " + DialogIdentiferName + "* dialog)\n" +
                           "{\n" +
                           "\t\n" +
                           "}\n";
                Form1.Form.OpenFile(DialogItem, DialogItem.CodeGUINode);
                CodeEditor.Text += s;
                focusAt = new TextPoint(lines + 4, 1);
            }
            else if (jumpToIt)
                Form1.Form.OpenFile(DialogItem, DialogItem.CodeGUINode);
            if (jumpToIt)
                CodeEditor.MoveCaretTo(focusAt);
        }
        public Point GetPixelAtTextpoint(TextPoint point, bool upper = true)
        {
            Rectangle textRegion = TextRegion;

            int hiddenLines = 0;
            for (int i = 0; i < point.Line && i < lines.Count; i++)
            {
                if (!lines[i].LineVisible)
                    hiddenLines++;
            }
            point.Line -= hiddenLines;

            Point p = new Point();
            p.Y = (point.Line - verticalScrollBar.Value)*fonts.Base.Height + textRegion.Y;
            p.X = (textRegion.X + 2 - horizontalScrollBar.Value);
            for (int i = 0; i < point.Pos; i++)
            {
                p.X += fonts.CharWidth;
                if (point.Line < lines.Count && point.Line >= 0 && i < lines[point.Line].Text.Length)
                {
                    if (lines[point.Line].Text[i] > 0xFF)
                        p.X += fonts.CharWidth;
                    else if (lines[point.Line].Text[i] == '\t')
                        p.X += 3*fonts.CharWidth;
                }
            }
            //p.X = (textRegion.X + 2 - horizontalScrollBar.Value + fonts.CharWidth * point.Pos);
            //p.X = fonts.GetWidth(lines[point.Line].Text.Substring(0, point.Pos));
            if (!upper)
                p.Y += fonts.Base.Height;
            return p;
        }
        /*
         * problems:
        set cursor to line (need to add/subtract invisible lines, when someone gets/sets cursor line)
        what happens if the cursor is set to an invisible line?
        what happens if the cursor is above an invisible line, and key down is pressed?
        what happens if the cursor is at pos 0 under an invisible line, and backspace is pressed?
        error messages will give a position in absolute line numbers.
        when to update blocks?
        when {, } is inserted.
        when text is deleted (marked text, delete and backspace)
        when text is pasted
        */
        private void UpdateBlocks()
        {
            List<TextPoint> openBrackets = new List<TextPoint>();
            List<Line> hiddenBlocks = new List<Line>();
            List<Line> changedToVisible = new List<Line>();
            List<Line> changedToHidden = new List<Line>();

            TextPoint point = new TextPoint(0, -1);
            int lastLine = -1;
            while (NextTextPoint(ref point))
            {

                for (int i = lastLine + 1; i <= point.Line; i++)
                {
                    if (!lines[i].BlockVisible)
                    {
                        hiddenBlocks.Add(lines[i]);
                        lines[i].BlockVisible = true;
                    }

                    if (!lines[i].LineVisible)
                        changedToVisible.Add(lines[i]);

                    lines[i].BlockEndLine = null;
                    lines[i].LineVisible = true;

                }
                lastLine = point.Line;

                char currentChar = lines[point.Line].Text[point.Pos];
                if (currentChar == '{')
                    openBrackets.Add(new TextPoint(point.Line, point.Pos));
                else if (currentChar == '}')
                {
                    //Find start point
                    if (openBrackets.Count > 0)
                    {
                        TextPoint openPoint = openBrackets[openBrackets.Count - 1];
                        openBrackets.RemoveAt(openBrackets.Count - 1);
                        //If there is another open bracket on the same line, this bracket can not be hidden.
                        if (openBrackets.Count == 0 || openBrackets[openBrackets.Count - 1].Line < openPoint.Line)
                        {
                            //Only add it if collapsing it causes some lines to be invis
                            if (openPoint.Line + 1< point.Line)
                            {
                                lines[openPoint.Line].BlockEndLine = lines[point.Line];
                                if (hiddenBlocks.Contains(lines[openPoint.Line]))
                                {//Hide lines between open and closed block
                                    lines[openPoint.Line].BlockVisible = false;
                                    for (int line = openPoint.Line + 1; line < point.Line; line++)
                                    {
                                        if (changedToVisible.Contains(lines[line]))
                                            changedToVisible.Remove(lines[line]);
                                        else
                                            changedToHidden.Add(lines[line]);

                                        lines[line].LineVisible = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            for (int i = lastLine + 1; i < point.Line; i++)
            {
                lines[i].BlockEndLine = null;
                lines[i].LineVisible = true;
                lines[i].BlockVisible = true;
            }

            ExtendedLines(changedToVisible);
            foreach (Line line in changedToHidden)
            {
                ShrunkLine(line);
            }

            if (changedToHidden.Count > 0 || changedToVisible.Count > 0)
            {
                InvalidateAll = true;
                Invalidate();
            }
        }
 private bool NextTextPoint(ref TextPoint point)
 {
     point.Pos++;
     if (point.Pos < lines[point.Line].Text.Length)
         return true;
     point.Line++;
     point.Pos = -1;
     if (point.Line < lines.Count)
         return NextTextPoint(ref point);
     return false;
 }
        private TextPoint GetTextpointAtPixel(int x, int y)
        {
            Rectangle textRegion = TextRegion;
            TextPoint point = new TextPoint();
            point.Line = Math.Max(0, (y - textRegion.Y) / fonts.Base.Height + verticalScrollBar.Value);
            for (int i = 0; i <= point.Line && i < lines.Count; i++)
            {
                if (!lines[i].LineVisible)
                    point.Line++;
            }
            if (point.Line >= lines.Count)
                point.Line = lines.Count - 1;
            point.Pos = (x - textRegion.X + horizontalScrollBar.Value);
            //p.Y = (point.Line - verticalScrollBar.Value) * fonts.Base.Height + textRegion.Y;
            int pos = 0;
            for (pos = 0; pos < lines[point.Line].Text.Length; pos++)
            {
                if (point.Pos < 0)
                    break;
                int subtract = fonts.CharWidth;
                if (lines[point.Line].Text[pos] > 0xFF)
                    subtract += fonts.CharWidth;
                else if (lines[point.Line].Text[pos] == '\t')
                    subtract += 3 * fonts.CharWidth;
                point.Pos -= subtract;
                if (point.Pos < 0)
                {
                    if (point.Pos > -subtract / 2)
                        pos++;
                    break;
                }
            }
            point.Pos = pos;
               /* if (point.Pos % fonts.CharWidth >= fonts.CharWidth / 2)
                point.Pos += fonts.CharWidth;
            point.Pos /= fonts.CharWidth;*/
            point.Pos = Math.Max(0, Math.Min(point.Pos, lines[point.Line].Text.Length));

            return point;
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.XButton1)
            {
                horizontalScrollBar.Value = Math.Max(0, Math.Min(horizontalScrollBar.Value + 50, horizontalScrollBar.Maximum));
                return;
            }
            if ( e.Button == MouseButtons.XButton2)
            {
                horizontalScrollBar.Value = Math.Max(0, Math.Min(horizontalScrollBar.Value - 50, horizontalScrollBar.Maximum));
                return;
            }

            bool shift = Control.ModifierKeys == Keys.Shift;
            Focus();

            if (Form1.Form.suggestionBox.Visible)
            {
                Form1.Form.suggestionBox.AllowHide = true;
                Form1.Form.suggestionBox.Hide();
            }

            if (TextRegion.Contains(e.Location))
            {
                if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
                {
                    if (TextMarked && !shift)
                    {
                        InvalidateAll = true;
                        TextMarked = false;
                    }
                    if (!TextMarked && shift)
                    {
                        mouseDownPos = caret.GetPosition(true);
                        TextMarked = true;
                    }
                    if (!shift)
                        mouseDownPos = GetTextpointAtPixel(e.X, e.Y);
                    else
                        InvalidateAll = true;
                    leftMouseDown = true;
                    lines[caret.GetPosition(true).Line].Invalidated = true;
                    caret.SetPosition(GetTextpointAtPixel(e.X, e.Y), true);
                    caret.Shown = true;
                    CaretMoved(false);
                    FindAndReplaceForm.form.ResetPos();
                    Invalidate();
                }
                //If double click
                lastMouseDownPos.X -= e.X;
                lastMouseDownPos.Y -= e.Y;
                lastMouseDownPos.X *= lastMouseDownPos.X;
                lastMouseDownPos.Y *= lastMouseDownPos.Y;
                if (!shift && (DateTime.Now - lastMouseDown).TotalMilliseconds < SystemInformation.DoubleClickTime &&
                    lastMouseDownPos.X < SystemInformation.DoubleClickSize.Width && lastMouseDownPos.Y < SystemInformation.DoubleClickSize.Height)
                {
                    //Mark current word
                    TextPoint caretPos = caret.GetPosition(true);
                    int min, max;
                    min = max = caretPos.Pos;
                    min--;
                    leftMouseDown = false;
                    while (min >= 0 && Util.IsIdentifierLetter(lines[caretPos.Line].Text[min]))
                        min--;
                    while (max < lines[caretPos.Line].Text.Length &&
                            Util.IsIdentifierLetter(lines[caretPos.Line].Text[max]))
                        max++;
                    min++;
                    mouseDownPos = new TextPoint(caretPos.Line, min);
                    caret.SetPosition(new TextPoint(caretPos.Line, max), true);
                    TextMarked = true;
                    //InvalidateAll = true;
                    lines[caretPos.Line].Invalidated = true;
                    caret.Shown = true;
                    Invalidate();
                }
                lastMouseDownPos = e.Location;
                lastMouseDown = DateTime.Now;
            }
            else
            {//Might have clicked a button to hide/show block
                int line = GetTextpointAtPixel(e.X, e.Y).Line;
                if (e.X < TextRegion.X && line < lines.Count && lines[line].BlockEndLine != null)
                {
                    bool visible = lines[line].BlockVisible = !lines[line].BlockVisible;
                    Line endLine = lines[line].BlockEndLine;
                    line++;
                    List<Line> modifiedLines = new List<Line>();
                    while (lines[line] != endLine)
                    {
                        modifiedLines.Add(lines[line]);
                        lines[line].LineVisible = visible;
                        //If we wanted to show the block, and it contains hidden blocks. dont show those
                        if (lines[line].BlockEndLine != null && lines[line].BlockVisible == false && visible)
                        {
                            Line anotherEndLine = lines[line].BlockEndLine;
                            while (lines[line] != anotherEndLine)
                            {
                                line++;
                            }
                            continue;
                        }
                        line++;
                    }
                    if (visible)
                        ShowedLines(modifiedLines);
                    else
                        HidLines(modifiedLines);

                    InvalidateAll = true;
                    Invalidate();
                }
            }
        }
        public void UndoRemove(TextPoint from, TextPoint to)
        {
            bool invalidateFollowingLines = from.Line != to.Line;
            lines[from.Line].Invalidated = true;
            lines[from.Line].edited = true;
            if (from.Line == to.Line)
                //Cut text between min and max
                lines[from.Line].Text = lines[from.Line].Text.Remove(from.Pos, to.Pos - from.Pos);
            else
                //Cut end of min line, and replace with end of max line
                lines[from.Line].Text = lines[from.Line].Text.Substring(0, from.Pos) + lines[to.Line].Text.Remove(0, to.Pos);
            //Cut lines between min and max
            while (from.Line < to.Line)
            {
                lines.RemoveAt(from.Line + 1);
                to.Line--;
            }

            if (invalidateFollowingLines)
            {//We removed a line - invalidate all following
                for (int i = from.Line; i < lines.Count; i++)
                {
                    lines[i].Invalidated = true;
                }
            }

            caret.SetPosition(new TextPoint(from.Line, from.Pos), true);
            //Dont know if it is shrunk or not, so call both :)
            ExtendedLines(new List<Line>() { lines[from.Line] });
            ShrunkLine(lines[from.Line]);
            UpdateBlocks();
            TextEdited();
            CaretMoved();
            Invalidate();
            Form1.Form.suggestionBox.Hide();
        }
            public override void CaseAMethodDecl(AMethodDecl node)
            {
                End = Start = TextPoint.FromCompilerCoords(node.GetName().Line, node.GetName().Pos);
                ReturnType = Util.TypeToString(node.GetReturnType());
                Name = node.GetName().Text;

                base.CaseAMethodDecl(node);
            }
            public override void CaseAInitializerDecl(AInitializerDecl node)
            {
                Name = "";
                ReturnType = "void";
                End = Start = TextPoint.FromCompilerCoords(node.GetToken().Line, node.GetToken().Pos);

                base.CaseAInitializerDecl(node);
            }
            public override void CaseADeconstructorDecl(ADeconstructorDecl node)
            {
                End = Start = TextPoint.FromCompilerCoords(node.GetName().Line, node.GetName().Pos);
                Name = node.GetName().Text;

                base.CaseADeconstructorDecl(node);
            }
        public MethodDescription(TextPoint start, PType returnType, AABlock block, PType propertyType)
        {
            Parser parser = new Parser(block);

            Start = start;
            End = parser.End;
            ReturnType = Util.TypeToString(returnType);
            Name = "";
            Formals = parser.Formals;
            Locals = parser.Locals;
            if (block.Parent() != null)
                block.Parent().RemoveChild(block);
            //Decl = initializer;
            IsStatic = false;
            realType = (PType) returnType.Clone();
            if (propertyType != null)
                this.propertyType = (PType)propertyType.Clone();
            Position = start;
        }
        public static void Parse(List<string> files, ErrorCollection errors)
        {
            /*
             * #macro <identifier>[(<identifiers>)]
             * anything...#arg1...anything
             *
             * #endmacro
             *
             * #<identifier>(anything_but_comma, #anything_but_hash#)
             *
             *
             */

            //Phase 1: locate all macros
            List<Macro> macros = new List<Macro>();
            for (int i = 0; i < files.Count; i++)
            {
                string source = files[i];

                Lexer lexer = new Lexer(new StringReader(source));
                List<Token> tokens = new List<Token>();
                Token token;
                while (!((token = lexer.Next()) is EOF))
                {
                    if (token is TWhiteSpace || token is TTraditionalComment || token is TDocumentationComment || token is TEndOfLineComment)
                        continue;
                    tokens.Add(token);
                }

                List<Util.Pair<TextPoint, TextPoint>> macroSpan = new List<Util.Pair<TextPoint, TextPoint>>();

                for (int j = 0; j < tokens.Count - 1; j++)
                {
                    int t = j;
                    if (tokens[t] is TSharp && tokens[t + 1].Text == "macro")
                    {
                        Macro macro = new Macro();
                        Token sharp = tokens[t];
                        macro.token = sharp;
                        TextPoint start = TextPoint.FromCompilerCoords(tokens[t]);
                        t += 2;
                        if (t >= tokens.Count || !(tokens[t] is TIdentifier))
                        {
                            errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText206")));
                            continue;
                        }
                        macro.Name = tokens[t].Text;
                        //Find end
                        TextPoint end = new TextPoint(-1, -1);
                        for (int k = t; k < tokens.Count - 1; k++)
                        {
                            if (tokens[k] is TSharp)
                            {
                                if (tokens[k + 1].Text == "macro")
                                {
                                    errors.Add(new ErrorCollection.Error(tokens[k],
                                                                         LocRM.GetString("ErrorText207"),
                                                                         false,
                                                                         new ErrorCollection.Error(sharp,
                                                                                                   LocRM.GetString("ErrorText208"))));
                                }
                                else if (tokens[k + 1].Text == "endmacro")
                                {
                                    end = TextPoint.FromCompilerCoords(tokens[k]);
                                    break;
                                }
                            }
                        }
                        if (end.Line == -1)
                        {
                            errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText209")));
                            continue;
                        }
                        //Check for parameters
                        t++;
                        TextPoint textStart;
                        if (tokens[t] is TLParen)
                        {
                            macro.Method = true;
                            bool needComma = false;
                            while (true)
                            {
                                t++;
                                if (tokens[t] is TRParen)
                                    break;
                                if (tokens[t] is TComma)
                                {
                                    if (!needComma)
                                    {
                                        errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText210")));
                                        break;
                                    }
                                    needComma = false;
                                    t++;
                                }
                                if (tokens[t] is TIdentifier)
                                {
                                    if (needComma)
                                    {
                                        errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText211")));
                                        break;
                                    }
                                    macro.Parameters.Add(tokens[t].Text);
                                    needComma = true;
                                    continue;
                                }
                                if (needComma)
                                    errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText211")));
                                else
                                    errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText210")));
                                break;
                            }
                            textStart = TextPoint.FromCompilerCoords(tokens[t]);
                            textStart.Pos++;
                            t++;
                        }
                        else
                        {
                            textStart = TextPoint.FromCompilerCoords(tokens[t - 1]);
                            textStart.Pos += macro.Name.Length;
                        }

                        macro.Text = GetText(source, textStart, end);
                        macroSpan.Add(new Util.Pair<TextPoint, TextPoint>(start, end));
                        macros.Add(macro);
                        j = t;
                    }
                }

                //Remove macros
                List<string> lines = source.Split('\n').ToList();
                for (int j = macroSpan.Count - 1; j >= 0; j--)
                {
                    TextPoint start = macroSpan[j].First;
                    TextPoint end = macroSpan[j].Second;

                    lines[start.Line] = lines[start.Line].Substring(0, start.Pos - 1) + lines[end.Line].Substring(end.Pos + "#endmacro".Length - 1);
                    for (int line = end.Line; line > start.Line; line--)
                    {
                        lines.RemoveAt(line);
                    }
                }

                StringBuilder builder = new StringBuilder();
                builder.Append(lines[0]);
                for (int j = 0; j < lines.Count; j++)
                {
                    builder.Append("\n" + lines[j]);
                }
                source = builder.ToString();

                files[i] = source;
            }

            //Check for dublicate macros
            for (int i = 0; i < macros.Count; i++)
            {
                List<Macro> conflicts = new List<Macro>(){macros[i]};
                for (int j = i + 1; j < macros.Count; j++)
                {
                    if (macros[i].Name == macros[j].Name &&
                        macros[i].Method == macros[j].Method &&
                        macros[i].Parameters.Count == macros[j].Parameters.Count)
                        conflicts.Add(macros[j]);
                }
                if (conflicts.Count > 1)
                {
                    List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                    foreach (Macro macro in conflicts)
                    {
                        subErrors.Add(new ErrorCollection.Error(macro.token, LocRM.GetString("ErrorText212")));
                        macros.Remove(macro);
                    }
                    errors.Add(new ErrorCollection.Error(conflicts[0].token, LocRM.GetString("ErrorText213"), false, subErrors.ToArray()));
                    i--;
                }
            }

            //Search for macro invocations

            for (int i = 0; i < files.Count; i++)
            {
                string source = files[i];
                ReplaceInvocations(ref source, macros, new List<Macro>(), errors);
                files[i] = source;
            }
        }
        private static string GetText(string source, TextPoint start, TextPoint end)
        {
            string[] lines = source.Split('\n');

            StringBuilder builder = new StringBuilder();
            if (start.Line == end.Line)
                builder.Append(lines[start.Line].Substring(start.Pos - 1, end.Pos - start.Pos - 1));
            else
            {
                builder.Append(lines[start.Line].Substring(start.Pos - 1) + "\n");
                for (int line = start.Line + 1; line < end.Line; line++)
                {
                    builder.Append(lines[line] + "\n");
                }
                builder.Append(lines[end.Line].Substring(0, end.Pos - 1));
            }
            return builder.ToString();
        }
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (PreviewKeyPress != null)
                PreviewKeyPress(this, e);

            if (!e.Handled && (e.KeyChar >= 32 && e.KeyChar <= 126 || e.KeyChar > 0xFF) && !IsReadonly)
            {
                DeleteMarkedText();
                TextPoint caretPos = caret.GetPosition(true);
                lines[caretPos.Line].Text = lines[caretPos.Line].Text.Insert(caretPos.Pos,
                                                                                         e.KeyChar.ToString());
                lines[caretPos.Line].Invalidated = true;
                lines[caretPos.Line].edited = true;
                string undoText = e.KeyChar.ToString();
                if (e.KeyChar == '{' && Options.Editor.InsertEndBracket)
                {
                    undoText += "}";
                    lines[caretPos.Line].Text = lines[caretPos.Line].Text.Insert(caretPos.Pos + 1,
                                                                                         "}");
                    //No need to update blocks here, as theese are on same line anyway
                }
                TextPoint undoPos = caretPos;
                if (e.KeyChar == ';' || e.KeyChar == '{' || e.KeyChar == ':')
                {
                    int unindentedCaretPos = caretPos.Pos;
                    foreach (char c in lines[caretPos.Line].Text)
                    {
                        if (c == ' ' || c == '\t')
                            unindentedCaretPos--;
                        else
                            break;
                    }

                    int spaces = 0;
                    foreach (char t in lines[caretPos.Line].Text)
                    {
                        if (t == ' ')
                            spaces--;
                        else if (t == '\t')
                            spaces -= 4;
                        else
                            break;
                    }
                    lines[caretPos.Line].Indents = lines[caretPos.Line].GetWantedIndents(fonts, lines, caretPos.Line);
                    spaces += 4*lines[caretPos.Line].Indents;
                    if (spaces > 0)
                    {
                        undoText = "";
                        for (int i = 0; i < spaces; i++)
                        {
                            undoText += ' ';
                        }
                        if (!Options.Editor.ReplaceTabsWithSpaces)
                            undoText = undoText.Replace("    ", "\t");
                        UndoSys.TextAdded(undoText, this, new TextPoint(caretPos.Line, 0));
                    }
                    if (spaces < 0)
                    {
                        undoText = "";
                        for (int i = 0; i < -spaces; i++)
                        {
                            undoText += ' ';
                        }
                        if (!Options.Editor.ReplaceTabsWithSpaces)
                            undoText = undoText.Replace("    ", "\t");
                        UndoSys.TextRemoved(undoText, this, new TextPoint(caretPos.Line, 0));
                    }
                    foreach (char c in lines[caretPos.Line].Text)
                    {
                        if (c == ' ' || c == '\t')
                            unindentedCaretPos++;
                        else
                            break;
                    }
                    if (unindentedCaretPos < 0)
                        unindentedCaretPos = 0;
                    caretPos = new TextPoint(caretPos.Line, unindentedCaretPos + 1);
                    caret.SetPosition(caretPos, true);

                }
                else if (e.KeyChar == '}')
                {//Fix indents
                    //Search for partner
                    int openBraces = 0;
                    int startLine = -1;
                    TextPoint currentPos = new TextPoint(caretPos.Line, caretPos.Pos - 1);
                    while (true)
                    {
                        while (currentPos.Pos < 0)
                        {
                            currentPos.Line--;
                            if (currentPos.Line < 0)
                                break;
                            currentPos.Pos = lines[currentPos.Line].Text.Length - 1;
                        }
                        if (currentPos.Line < 0)
                            break;

                        char ch = lines[currentPos.Line].Text[currentPos.Pos];
                        if (ch == '}')
                            openBraces++;
                        else if (ch == '{')
                        {
                            if (openBraces > 0)
                                openBraces--;
                            else
                            {
                                startLine = currentPos.Line;
                                break;
                            }
                        }
                        currentPos.Pos--;
                    }

                    if (startLine >= 0)
                    {
                        string oldText = "";
                        for (int i = startLine; i <= caretPos.Line; i++)
                        {
                            oldText += lines[i].Text;
                            if (i != caretPos.Line)
                                oldText += "\n";
                        }
                        string insertedOldText = "";
                        for (int i = startLine; i <= caretPos.Line; i++)
                        {
                            if (i == caretPos.Line)
                                insertedOldText += lines[i].Text.Substring(0, caretPos.Pos);
                            else
                                insertedOldText += lines[i].Text + "\n";

                        }

                        int spaces = 0;
                        foreach (char t in lines[caretPos.Line].Text)
                        {
                            if (t == ' ')
                                spaces--;
                            else if (t == '\t')
                                spaces -= 4;
                            else
                                break;
                        }
                        for (int i = startLine; i <= caretPos.Line; i++)
                        {
                            lines[i].Indents = lines[i].GetWantedIndents(fonts, lines, i);
                        }

                        string newText = "";
                        for (int i = startLine; i <= caretPos.Line; i++)
                        {
                            newText += lines[i].Text;
                            if (i != caretPos.Line)
                                newText += "\n";
                        }

                        if (oldText != newText)
                        {
                            undoText = "";
                            //Remove the { from oldText

                            UndoSys.TextReplaced(insertedOldText, newText, this, new TextPoint(startLine, 0));
                        }

                        spaces += 4 * lines[caretPos.Line].Indents;
                        if (!Options.Editor.ReplaceTabsWithSpaces) spaces /= 4;

                        caretPos = new TextPoint(caretPos.Line, caretPos.Pos + 1 + spaces);
                        caret.SetPosition(caretPos, true);

                    }
                    else
                    {
                        caretPos = new TextPoint(caretPos.Line, caretPos.Pos + 1);
                        caret.SetPosition(caretPos, true);
                    }

                    UpdateBlocks();
                }
                else
                {
                    caretPos = new TextPoint(caretPos.Line, caretPos.Pos + 1);
                    caret.SetPosition(caretPos, true);
                }
                if (undoText != "")
                    UndoSys.TextAdded(undoText, this, undoPos);
                e.Handled = true;
                ExtendedLines(new List<Line>() {lines[caretPos.Line]});
                TextEdited();
                CaretMoved();
                Invalidate();
            }

            base.OnKeyPress(e);
        }
        public MethodDescription(AInitializerDecl initializer)
        {
            Parser parser = new Parser(initializer);

            Start = parser.Start;
            End = parser.End;
            ReturnType = parser.ReturnType;
            Name = parser.Name;
            Formals = parser.Formals;
            Locals = parser.Locals;
            if (initializer.Parent() != null)
                initializer.Parent().RemoveChild(initializer);
            //Decl = initializer;
            IsStatic = false;
            Position = TextPoint.FromCompilerCoords(initializer.GetToken());
        }
 private void DrawString(Graphics g, int lineNr, string text, Rectangle bounds)
 {
     for (int i = 0; i <= text.Length; i++)
     {
         TextPoint textPoint = new TextPoint(lineNr, i);
         if (IsTextpointMarked(textPoint))
         {
             Point pixel = GetPixelAtTextpoint(textPoint);
             int width = fonts.CharWidth;
             if (i < text.Length && text[i] > 0xFF)
                 width += fonts.CharWidth;
             else if (i < text.Length && text[i] == '\t')
                 width = 4*fonts.CharWidth;
             g.FillRectangle(new SolidBrush(Color.FromArgb(173, 214, 255)), pixel.X,
                             pixel.Y, width, fonts.Base.Height);
         }
     }
     Font font = new Font(fonts.Base, lines[lineNr].GetFontStyle(0).Style);
     int x = bounds.X;
     for (int i = 0; i < text.Length; i++)
     {
         FontModification modification = lines[lineNr].GetFontStyle(i);
         if (font.Style != modification.Style)
             font = new Font(fonts.Base, modification.Style);
         g.DrawString(text[i].ToString(), font, new SolidBrush(modification.Color), x, bounds.Y);
         x += fonts.CharWidth;
         if (text[i] > 0xFF)
             x += fonts.CharWidth;
         else if (text[i] == '\t')
             x += 3*fonts.CharWidth;
     }
 }
        public string GetTextWithin(TextPoint begin, TextPoint end)
        {
            if (end.Line >= lines.Count)
                end.Line = lines.Count - 1;
            if (begin.Line == end.Line)
                return lines[begin.Line].Text.Substring(begin.Pos, end.Pos - begin.Pos);
            StringBuilder text = new StringBuilder(lines[begin.Line].Text.Substring(begin.Pos) + "\n");

            for (int i = begin.Line + 1; i < end.Line; i++)
            {
                text.Append(lines[i].Text + "\n");
            }
            if (end.Pos < lines[end.Line].Text.Length)
                text.Append(lines[end.Line].Text.Remove(end.Pos));
            else
                text.Append(lines[end.Line].Text);
            return text.ToString();
        }
 private bool IsTextpointMarked(TextPoint point)
 {
     TextPoint min = TextPoint.Min(caret.GetPosition(true), mouseDownPos);
     TextPoint max = TextPoint.Max(caret.GetPosition(true), mouseDownPos);
     return TextMarked && point >= min && point < max;
 }
        public void InsertAndStyle(TextPoint pos, string text)
        {
            UndoInsert(pos, text);
            int lineBreaks = text.Count(c => c == '\n');
            TextPoint endPos = new TextPoint(pos.Line + lineBreaks, 0);

            int lastLineLength = text.Remove(0, text.LastIndexOf('\n') + 1).Length;

            for (int i = 0; i <= lineBreaks; i++)
            {
                int oldWhiteSpaceCount = 0;
                if (i == lineBreaks)
                {
                    oldWhiteSpaceCount = lines[pos.Line + i].Text.Count(c => c == ' ' || c == '\t');
                }

                lines[pos.Line + i].Indents = lines[pos.Line + i].GetWantedIndents(fonts, lines, pos.Line + i);

                if (i == lineBreaks)
                {
                    endPos.Pos = lastLineLength - oldWhiteSpaceCount +
                                 lines[pos.Line + i].Text.Count(c => c == ' ' || c == '\t');
                }
            }

            UndoSys.TextAdded(GetTextWithin(pos, endPos), this, pos);
        }
        public bool ExecuteKey(KeyEventArgs e)
        {
            TextPoint caretPos = caret.GetPosition(true);
            bool shift = e.Shift;
            bool ctrl = e.Control;
            Keys keys = e.KeyData;
            if (shift) keys = e.KeyData ^ Keys.Shift;
            if (ctrl) keys = keys ^ Keys.Control;
            //Only handle special keys

            switch (keys)
            {
                case Keys.Tab:

                    if (IsReadonly) break;
                    if (!TextMarked)
                    {
                        if (!Options.Editor.ReplaceTabsWithSpaces)
                        {
                            lines[caretPos.Line].Text = lines[caretPos.Line].Text.Insert(caretPos.Pos, "\t");
                            lines[caretPos.Line].Invalidated = true;

                            UndoSys.TextAdded("\t", this, caretPos);
                            caretPos.Pos++;
                            caret.SetPosition(caretPos, true);
                            ExtendedLines(new List<Line>() { lines[caretPos.Line] });
                            Invalidate();
                            TextEdited();
                            CaretMoved(false);
                            return true;
                        }

                        int pos;
                        if (shift)
                        {//Remove spaces up to previous tab
                            int count = 0;
                            while (caretPos.Pos > 0 && lines[caretPos.Line].Text[caretPos.Pos - count - 1] == ' ')
                            {
                                if (caretPos.Pos - count == 0)
                                    break;
                                count++;
                                if ((caretPos.Pos - count) % 4 == 0)
                                {
                                    break;
                                }
                            }
                            if (count == 0)
                                return true;
                            UndoSys.TextRemoved(lines[caretPos.Line].Text.Substring(caretPos.Pos - count, count), this, new TextPoint(caretPos.Line, caretPos.Pos - count));
                            lines[caretPos.Line].Text = lines[caretPos.Line].Text.Remove(caretPos.Pos - count, count);
                            lines[caretPos.Line].Invalidated = true;
                            caretPos.Pos -= count;
                            caret.SetPosition(caretPos, true);
                            ShrunkLine(lines[caretPos.Line]);
                            Invalidate();
                            TextEdited();
                            CaretMoved(false);
                            return true;
                        }

                        pos = caretPos.Pos + 1;
                        string textInsert = " ";
                        while (pos % 4 > 0)
                        {
                            pos++;
                            textInsert += " ";
                        }
                        lines[caretPos.Line].Text = lines[caretPos.Line].Text.Insert(caretPos.Pos, textInsert);
                        lines[caretPos.Line].Invalidated = true;

                        UndoSys.TextAdded(textInsert, this, caretPos);
                        caretPos.Pos += textInsert.Length;
                        caret.SetPosition(caretPos, true);
                        ExtendedLines(new List<Line>(){lines[caretPos.Line]});
                        Invalidate();
                        TextEdited();
                        CaretMoved(false);
                        return true;
                    }

                    List<Line> modifiedLines = new List<Line>();
                    int min = Math.Min(caretPos.Line, mouseDownPos.Line);
                    int max = Math.Max(caretPos.Line, mouseDownPos.Line);

                    string oldText = "";
                    for (int i = min; i <= max; i++)
                    {
                        oldText += lines[i].Text;
                        if (i != max)
                            oldText += "\n";
                    }

                    string newText;
                    /*if (!Options.Editor.ReplaceTabsWithSpaces)
                    {
                        newText = "";
                        for (int i = min; i <= max; i++)
                        {
                            lines[i].Indents++;
                            lines[i].Invalidated = true;
                            newText += lines[i].Text;
                        }
                    }*/
                    int spacesCaret = 0;
                    foreach (char t in lines[caretPos.Line].Text)
                    {
                        if (t == ' ')
                            spacesCaret--;
                        else
                            break;
                    }
                    int spacesMarkStart = 0;
                    foreach (char t in lines[mouseDownPos.Line].Text)
                    {
                        if (t == ' ')
                            spacesMarkStart--;
                        else
                            break;
                    }
                    for (int i = min; i <= max; i++)
                    {
                        modifiedLines.Add(lines[i]);
                        lines[i].Invalidated = true;
                        if (e.Shift)
                            lines[i].Indents--;
                        else
                            lines[i].Indents++;
                    }
                    newText = "";
                    for (int i = min; i <= max; i++)
                    {
                        newText += lines[i].Text;
                        if (i != max)
                            newText += "\n";
                    }
                    UndoSys.TextReplaced(oldText, newText, this, new TextPoint(min, 0));

                    spacesCaret += 4 * lines[caretPos.Line].Indents;
                    if (!Options.Editor.ReplaceTabsWithSpaces && spacesCaret != 0) spacesCaret /= Math.Abs(spacesCaret);
                    if (caretPos.Pos + spacesCaret < 0)
                        spacesCaret = -caretPos.Pos;
                    caretPos = new TextPoint(caretPos.Line, caretPos.Pos + spacesCaret);
                    caret.SetPosition(caretPos, true);

                    spacesMarkStart += 4 * lines[mouseDownPos.Line].Indents;
                    if (!Options.Editor.ReplaceTabsWithSpaces && spacesMarkStart != 0)  spacesMarkStart /= Math.Abs(spacesMarkStart);
                    mouseDownPos = new TextPoint(mouseDownPos.Line, mouseDownPos.Pos + spacesMarkStart);

                    ExtendedLines(modifiedLines);
                    Invalidate();
                    TextEdited();
                    CaretMoved(false);
                    return true;
                case Keys.Delete:
                    if (IsReadonly) break;
                    if (TextMarked)
                    {
                        DeleteMarkedText();
                        caretPos = caret.GetPosition(true);
                    }
                        //Li|ne1
                    else if (lines[caretPos.Line].Text.Length > caretPos.Pos)
                    {
                        string removedPart = lines[caretPos.Line].Text.Substring(caretPos.Pos, 1);
                        UndoSys.TextRemoved(removedPart, this, new TextPoint(caretPos.Line, caretPos.Pos));
                        lines[caretPos.Line].Text = lines[caretPos.Line].Text.Remove(caretPos.Pos, 1);
                        lines[caretPos.Line].edited = true;
                        lines[caretPos.Line].Invalidated = true;
                        ShrunkLine(lines[caretPos.Line]);
                        UpdateBlocks();
                        Invalidate();
                        TextEdited();
                    }
                    //Line1|
                    //Line2
                    else if (lines.Count > caretPos.Line + 1)
                    {
                        UndoSys.TextRemoved("\n", this, new TextPoint(caretPos.Line, caretPos.Pos));
                        lines[caretPos.Line].Text += lines[caretPos.Line + 1].Text;
                        lines[caretPos.Line].edited = true;
                        lines.RemoveAt(caretPos.Line + 1);
                        //InvalidateAll = true;
                        for (int i = caretPos.Line; i < lines.Count; i++)
                        {
                            lines[i].Invalidated = true;
                        }
                        ExtendedLines(new List<Line>{lines[caretPos.Line]});
                        UpdateBlocks();
                        Invalidate();
                        TextEdited();
                    }
                    return true;
                case Keys.Back:
                    if (IsReadonly) break;
                    if (TextMarked)
                    {
                        DeleteMarkedText();
                        caretPos = caret.GetPosition(true);
                    }
                    //Li|ne1
                    else if (caretPos.Pos > 0)
                    {
                        string removedPart = lines[caretPos.Line].Text.Substring(
                            caretPos.Pos - 1, 1);
                        lines[caretPos.Line].Text = lines[caretPos.Line].Text.Remove(
                            caretPos.Pos - 1, 1);
                        lines[caretPos.Line].Invalidated = true;
                        lines[caretPos.Line].edited = true;
                        UndoSys.TextRemoved(removedPart, this, new TextPoint(caretPos.Line, caretPos.Pos - 1));
                        caret.SetPosition(new TextPoint(caretPos.Line, caretPos.Pos - 1), true);
                        ShrunkLine(lines[caretPos.Line]);
                        UpdateBlocks();
                        Invalidate();
                        TextEdited();
                    }
                    //Line1
                    //|Line2
                    else if (caretPos.Line > 0)
                    {
                        TextPoint newPos = new TextPoint(caretPos.Line - 1,
                                                         lines[caretPos.Line - 1].Text.Length);
                        lines[caretPos.Line - 1].Text += lines[caretPos.Line].Text;
                        lines.RemoveAt(caretPos.Line);
                        //InvalidateAll = true;
                        for (int l = caretPos.Line - 1; l < lines.Count; l++)
                        {
                            lines[l].Invalidated = true;
                        }
                        UndoSys.TextRemoved("\n", this, new TextPoint(newPos.Line, newPos.Pos));
                        caret.SetPosition(newPos, true);
                        lines[newPos.Line].edited = true;
                        ExtendedLines(new List<Line> { lines[newPos.Line] });
                        UpdateBlocks();
                        Invalidate();
                        TextEdited();
                        CaretMoved();
                        return true;
                    }
                    CaretMoved();
                    return true;
                case Keys.Return:
                    if (IsReadonly) break;
                    DeleteMarkedText();
                    caretPos = caret.GetPosition(true);
                    List<Line> newLines = new List<Line>();
                    Line newLine = new Line(lines[caretPos.Line].Text.Substring(caretPos.Pos));
                    newLines.Add(newLine);
                    Line extraNewLine = null;
                    string undoText = "\n";
                    //If the next char was an }, move that to its own line
                    if (newLine.Text.Length > 0 && newLine.Text[0] == '}')
                    {
                        extraNewLine = new Line(newLine.Text);
                        newLines.Add(extraNewLine);
                        lines.Insert(caretPos.Line + 1, extraNewLine);
                        newLine.Text = "";
                    }
                    string oldNewLineText = newLine.Text;
                    lines.Insert(caretPos.Line + 1, newLine);
                    lines[caretPos.Line].Text = lines[caretPos.Line].Text.Substring(0, caretPos.Pos);
                    lines[caretPos.Line].edited = true;
                    lines[caretPos.Line].Restyle(fonts, lines, caretPos.Line);
                    newLine.Indents = newLine.GetWantedIndents(fonts, lines, caretPos.Line + 1);
                    if (newLine.Text.Length - oldNewLineText.Length >= 0 && oldNewLineText.Length > 0)
                        undoText += newLine.Text.Remove(newLine.Text.Length - oldNewLineText.Length);
                    else
                        undoText += newLine.Text;
                    if (extraNewLine != null)
                    {
                        oldNewLineText = extraNewLine.Text;
                        extraNewLine.Indents = extraNewLine.GetWantedIndents(fonts, lines, caretPos.Line + 2);
                        if (extraNewLine.Text.Length - oldNewLineText.Length >= 0 && oldNewLineText.Length > 0)
                            undoText += "\n" + extraNewLine.Text.Remove(extraNewLine.Text.Length - oldNewLineText.Length);
                        else
                            undoText += "\n" + extraNewLine.Text;
                    }

                    caret.SetPosition(new TextPoint(caretPos.Line + 1, Options.Editor.ReplaceTabsWithSpaces ? newLine.Indents*4 : newLine.Indents), true);
                    //InvalidateAll = true;
                    for (int l = caretPos.Line; l < lines.Count; l++)
                    {
                        lines[l].Invalidated = true;
                    }
                    ShrunkLine(lines[caretPos.Line]);
                    ExtendedLines(newLines);
                    UndoSys.TextAdded(undoText, this, caretPos);
                    UpdateBlocks();
                    Invalidate();
                    TextEdited();
                    CaretMoved();
                    return true;
                case Keys.Right:
                    if (!TextMarked)
                    {
                        TextMarked = shift;
                        mouseDownPos = caretPos;
                    }
                    //if (!shift)
                    //    TextMarked = false;
                    while (true)
                    {
                        if (lines[caretPos.Line].Text.Length > caretPos.Pos)
                        {
                            lines[caretPos.Line].Invalidated = true;

                            int pos = caretPos.Pos + 1;

                            if (ctrl)
                            {
                                List<Token> tokens = new List<Token>();
                                Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text));
                                {
                                    Token token;
                                    while (!((token = lexer.Next()) is EOF))
                                    {
                                        if (token is TWhiteSpace)
                                            continue;
                                        tokens.Add(token);
                                    }
                                }
                                bool moved = false;
                                foreach (Token token in tokens)
                                {
                                    if (token.Pos - 1 >= pos)
                                    {
                                        pos = token.Pos - 1;
                                        moved = true;
                                        break;
                                    }
                                }
                                if (!moved)
                                {
                                    caretPos.Pos = lines[caretPos.Line].Text.Length;
                                    continue;
                                }
                            }

                            caret.SetPosition(new TextPoint(caretPos.Line, pos), true);
                            Invalidate();
                        }
                        else if (lines.Count > caretPos.Line + 1)
                        {
                            lines[caretPos.Line].Invalidated = true;
                            //Skip over any potential hidden lines
                            caret.SetPosition(new TextPoint(caret.GetPosition(false).Line + 1, 0), false);

                            if (ctrl)
                            {
                                caretPos = caret.GetPosition(true);
                                int pos = caretPos.Pos;
                                List<Token> tokens = new List<Token>();
                                Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text));
                                {
                                    Token token;
                                    while (!((token = lexer.Next()) is EOF))
                                    {
                                        if (token is TWhiteSpace)
                                            continue;
                                        tokens.Add(token);
                                    }
                                }
                                if (tokens.Count > 0)
                                {
                                    Token token = tokens[0];
                                    pos = token.Pos - 1;
                                }
                                else
                                    pos = lines[caretPos.Line].Text.Length;
                                caret.SetPosition(new TextPoint(caretPos.Line, pos), true);
                            }
                            Invalidate();
                        }
                        break;
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.Left:
                    if (!TextMarked)
                    {
                        TextMarked = shift;
                        mouseDownPos = caretPos;
                    }
                    //if (!shift)
                    //    TextMarked = false;
                    while (true)
                    {
                        if (caretPos.Pos > 0)
                        {
                            lines[caretPos.Line].Invalidated = true;
                            int pos = caretPos.Pos - 1;

                            if (ctrl)
                            {
                                List<Token> tokens = new List<Token>();
                                Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text));
                                {
                                    Token token;
                                    while (!((token = lexer.Next()) is EOF))
                                    {
                                        if (token is TWhiteSpace)
                                            continue;
                                        tokens.Add(token);
                                    }
                                }
                                bool moved = false;
                                for (int i = tokens.Count - 1; i >= 0; i--)
                                {
                                    Token token = tokens[i];
                                    if (token.Pos - 1 <= pos)
                                    {
                                        pos = token.Pos - 1;
                                        moved = true;
                                        break;
                                    }
                                }
                                if (!moved)
                                {
                                    caretPos.Pos = 0;
                                    continue;
                                }
                            }

                            caret.SetPosition(new TextPoint(caretPos.Line, pos), true);
                            Invalidate();
                        }
                        else if (caretPos.Line > 0)
                        {
                            lines[caretPos.Line].Invalidated = true;
                            //Skip over any potential hidden lines
                            caret.SetPosition(new TextPoint(caret.GetPosition(false).Line - 1, 0), false);
                            caretPos = caret.GetPosition(true);
                            caret.SetPosition(new TextPoint(caretPos.Line, lines[caretPos.Line].Text.Length), true);

                            if (ctrl)
                            {
                                caretPos = caret.GetPosition(true);
                                int pos = caretPos.Pos;
                                List<Token> tokens = new List<Token>();
                                Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text));
                                {
                                    Token token;
                                    while (!((token = lexer.Next()) is EOF))
                                    {
                                        if (token is TWhiteSpace)
                                            continue;
                                        tokens.Add(token);
                                    }
                                }
                                if (tokens.Count > 0)
                                {
                                    Token token = tokens[tokens.Count - 1];
                                    pos = token.Pos - 1 + token.Text.Length;
                                }
                                caret.SetPosition(new TextPoint(caretPos.Line, pos), true);
                            }

                            Invalidate();
                        }
                        break;
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.Up:
                    if (!TextMarked)
                    {
                        TextMarked = shift;
                        mouseDownPos = caretPos;
                    }
                    //if (!shift)
                    //    TextMarked = false;
                    if (caretPos.Line > 0)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        lines[caretPos.Line - 1].Invalidated = true;

                        int oldPos = 0;
                        for (int i = 0; i < caretPos.Pos; i++)
                        {
                            oldPos++;
                            if (lines[caretPos.Line].Text[i] == '\t')
                                oldPos += 3;
                            else if (lines[caretPos.Line].Text[i] > 0xFF)
                                oldPos++;
                        }
                        caret.SetPosition(new TextPoint(caret.GetPosition(false).Line - 1, 0), false);
                        caretPos = caret.GetPosition(true);
                        int newPos = 0;
                        for (newPos = 0; newPos < lines[caretPos.Line].Text.Length; newPos++)
                        {
                            if (oldPos <= 0)
                                break;
                            if (lines[caretPos.Line].Text[newPos] == '\t')
                            {
                                oldPos -= 4;
                                if (oldPos < -2)
                                {
                                    newPos--;
                                }
                            }
                            else if (lines[caretPos.Line].Text[newPos] > 0xFF)
                                oldPos -= 2;
                            else
                                oldPos--;
                        }
                        caret.SetPosition(new TextPoint(caretPos.Line, /*Math.Min(lines[caretPos.Line].Text.Length, oldPos)*/newPos), true);
                        Invalidate();
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.Down:
                    if (!TextMarked)
                    {
                        TextMarked = shift;
                        mouseDownPos = caretPos;
                    }
                    //if (!shift)
                    //    TextMarked = false;
                    if (caretPos.Line + 1 < lines.Count)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        lines[caretPos.Line + 1].Invalidated = true;
                        int oldPos = 0;
                        for (int i = 0; i < caretPos.Pos; i++)
                        {
                            oldPos++;
                            if (lines[caretPos.Line].Text[i] == '\t')
                                oldPos += 3;
                            else if (lines[caretPos.Line].Text[i] > 0xFF)
                                oldPos++;
                        }
                        caret.SetPosition(new TextPoint(caret.GetPosition(false).Line + 1, 0), false);
                        caretPos = caret.GetPosition(true);
                        int newPos = 0;
                        for (newPos = 0; newPos < lines[caretPos.Line].Text.Length; newPos++)
                        {
                            if (oldPos <= 0)
                                break;
                            if (lines[caretPos.Line].Text[newPos] == '\t')
                            {
                                oldPos -= 4;
                                if (oldPos < -2)
                                {
                                    newPos--;
                                }
                            }
                            else if (lines[caretPos.Line].Text[newPos] > 0xFF)
                                oldPos -= 2;
                            else
                                oldPos--;
                        }
                        caret.SetPosition(new TextPoint(caretPos.Line, /*Math.Min(lines[caretPos.Line].Text.Length, oldPos)*/newPos), true);
                        Invalidate();
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.End:
                    if (!TextMarked)
                    {
                        TextMarked = true;
                        mouseDownPos = caretPos;
                    }
                    if (!shift)
                        TextMarked = false;
                    if (caretPos.Pos < lines[caretPos.Line].Text.Length)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        caret.SetPosition(new TextPoint(caretPos.Line, lines[caretPos.Line].Text.Length), true);
                        Invalidate();
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.Home:
                    if (!TextMarked)
                    {
                        TextMarked = true;
                        mouseDownPos = caretPos;
                    }
                    if (!shift)
                        TextMarked = false;
                    if (caretPos.Pos > 0)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        caret.SetPosition(new TextPoint(caretPos.Line, 0), true);
                        Invalidate();
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.PageUp:
                    if (!TextMarked)
                    {
                        TextMarked = true;
                        mouseDownPos = caretPos;
                    }
                    if (!shift)
                        TextMarked = false;
                    if (caretPos.Line > 0)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        int line = caretPos.Line;
                        int subtractedLines = 40;
                        while (line > 0 && subtractedLines > 0)
                        {
                            line--;
                            if (lines[line].LineVisible)
                                subtractedLines--;
                        }
                        int pos = caretPos.Pos;
                        if (pos > lines[line].Text.Length)
                            pos = lines[line].Text.Length;
                        caret.SetPosition(new TextPoint(line, pos), true);
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.PageDown:
                    if (!TextMarked)
                    {
                        TextMarked = true;
                        mouseDownPos = caretPos;
                    }
                    if (!shift)
                        TextMarked = false;
                    if (caretPos.Line + 1 < lines.Count)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        int line = caretPos.Line;
                        int addedLines = 40;
                        while (line < lines.Count - 1 && addedLines > 0)
                        {
                            line++;
                            if (lines[line].LineVisible)
                                addedLines--;
                        }
                        int pos = caretPos.Pos;
                        if (pos > lines[line].Text.Length)
                            pos = lines[line].Text.Length;
                        caret.SetPosition(new TextPoint(line, pos), true);

                    }
                    CaretMoved(!shift);
                    return true;
            }
            //Handle ctrl commands
            if (e.Modifiers == Keys.Control)
            {
                //Copy
                if (e.KeyValue != 17)
                    e = e;
                if (e.KeyValue == 'C' || e.KeyValue == 'X')
                {
                    Copy(e.KeyValue == 'X');
                    return true;
                }

                //Paste
                if (e.KeyValue == 'V' && !IsReadonly)
                {
                    Paste();
                    return true;
                }

                //Goto line
                if (e.KeyValue == 'G')
                {
                    GotoLineForm dialog = new GotoLineForm(caretPos.Line + 1, lines.Count);
                    if (dialog.ShowDialog(parentForm) == DialogResult.OK)
                    {
                        caret.SetPosition(new TextPoint(dialog.SelectedLine - 1, 0), true);
                        EnsureLineVisible(dialog.SelectedLine - 1);
                        CaretMoved();
                    }
                    return true;
                }

                if (e.KeyValue == 'A')
                {
                    mouseDownPos = new TextPoint(0, 0);
                    caret.SetPosition(new TextPoint(lines.Count - 1, lines[lines.Count - 1].Text.Length), true);
                    TextMarked = true;
                    InvalidateAll = true;
                    CaretMoved(false);
                    return true;
                }

                if (e.KeyValue  == 'F' || e.KeyValue == 'R')
                {
                    //FindAndReplaceForm.form.SetStart(((Form1.OpenFileData)Tag).File, caretPos);
                    OpenFindAndReplace();
                    return true;
                }

                if (e.KeyValue == 'Z')
                {
                    UndoSys.Undo();
                    return true;
                }

                if (e.KeyValue == 'Y')
                {
                    UndoSys.Redo();
                    return true;
                }
            }
            return false;
        }
        public void Mark(TextPoint from, TextPoint to)
        {
            if (TextMarked)
            {
                TextPoint min = TextPoint.Min(mouseDownPos, caret.GetPosition(true));
                TextPoint max = TextPoint.Max(mouseDownPos, caret.GetPosition(true));
                for (int i = min.Line; i <= max.Line; i++)
                {
                    lines[i].Invalidated = true;
                }
            }

            mouseDownPos = from;
            caret.SetPosition(to, true);
            for (int i = from.Line; i <= to.Line; i++)
            {
                lines[i].Invalidated = true;
            }
            TextMarked = true;
            EnsureLineVisible(to.Line);
            CaretMoved(false);
            Invalidate();
        }
 public void SetPosition(TextPoint pos, bool absolute)
 {
     if (!absolute)
     {
         for (int i = 0; i <= pos.Line; i++)
         {
             if (!owner.lines[i].LineVisible)
                 pos.Line++;
         }
     }
     Position = pos;
 }
 public void MoveCaretTo(TextPoint pos)
 {
     if (pos.Line >= lines.Count)
         pos.Line = lines.Count - 1;
     lines[caret.GetPosition(true).Line].Invalidated = true;
     caret.SetPosition(pos, true);
     EnsureLineVisible(pos.Line);
     CaretMoved();
     Invalidate();
 }
        private void TSInsertConstructor_Click(object sender, EventArgs e)
        {
            //Step 1: Find struct/class/enrichment at cursor
            //Step 2: Prompt the user to select the variables to initialize
            //Step 3: Generate and insert text. As close to cursor as possible.

            //Step 1
            StructDescription str = null;
            TextPoint currentPos;
            MyEditor editor = null;

            if (CurrentOpenFile == null)
            {
                foreach (DialogItem file in GetDialogsFiles(openProjectSrcDir))
                {
                    //bool isDesigner = file.OpenFileData.DesignerTabPage == tabStrip.SelectedItem;
                    if (file.OpenFileData != null &&
                        (file.OpenFileData.CodeTabPage == tabStrip.SelectedItem))
                    {
                        editor = file.OpenFileData.CodeEditor;
                        currentPos = file.OpenFileData.CodeEditor.caret.GetPosition(true);
                        foreach (SourceFileContents srcFile in compiler.ParsedSourceFiles)
                        {
                            if (srcFile.Item == file && !srcFile.IsDialogDesigner)
                            {
                                foreach (StructDescription s in srcFile.GetAllStructs())
                                {
                                    if (s.LineFrom - 1 <= currentPos.Line && s.LineTo - 1 >= currentPos.Line)
                                    {
                                        str = s;
                                        break;
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                editor = CurrentOpenFile.OpenFile.Editor;
                currentPos = CurrentOpenFile.OpenFile.Editor.caret.GetPosition(true);
                foreach (SourceFileContents file in compiler.ParsedSourceFiles)
                {
                    if (file.Item == CurrentOpenFile)
                    {
                        foreach (StructDescription s in file.GetAllStructs())
                        {
                            if (s.LineFrom - 1 <= currentPos.Line && s.LineTo - 1 >= currentPos.Line)
                            {
                                str = s;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            if (str == null)
            {
                MessageBox.Show(this, LocRM.GetString("Text44.Text"));
                return;
            }

            //Step 2
            List<VariableDescription> variables = new List<VariableDescription>();
            variables.AddRange(str.Fields);
            TextPoint lastFieldPos = new TextPoint(0, 0);
            foreach (VariableDescription variable in variables)
            {
                if (variable.Line > lastFieldPos.Line)
                    lastFieldPos.Line = variable.Line;
            }
            NewConstructorForm dialog = new NewConstructorForm(variables);
            if (dialog.ShowDialog(this) != DialogResult.OK)
                return;
            variables = dialog.SelectedOrder;

            //Step 3
            string insertHead = "\n" + str.Name + "(";
            string insertBody = "{\n";
            bool isFirst = true;
            foreach (VariableDescription variable in variables)
            {
                if (!isFirst)
                    insertHead += ", ";
                else
                    isFirst = false;
                string paramName = variable.Name;
                paramName = char.ToLower(paramName[0]) + paramName.Remove(0, 1);

                insertHead += variable.Type + " " + paramName;
                if (paramName == variable.Name)
                    insertBody += "this->";
                insertBody += variable.Name + " = " + paramName + ";\n";
            }
            string insert = insertHead + ")\n" + insertBody + "}\n";

            //Insert after the last field

            editor.InsertAndStyle(lastFieldPos, insert);
        }
        private List<AMethodDecl> GetMatchingCurrentMethod(out int commaCount, out TextPoint parenPos, out bool isAsyncInvoke)
        {
            isAsyncInvoke = false;
            commaCount = 0;
            parenPos = new TextPoint(0, 0);
            string text = currentEditor.GetTextWithin(new TextPoint(0, 0), currentEditor.caret.Position);

            Lexer lexer = new Lexer(new StringReader(text));
            List<Token> tokens = new List<Token>();
            Token token;
            bool inString = false;
            while (true)
            {
                try
                {
                    token = lexer.Next();
                    if (token is EOF)
                        break;
                }
                catch (Exception err)
                {
                    continue;
                }
                //We can be in a string if there was an unclosed " on this line
                if (token is TUnknown && token.Text == "\"" || token.Text == "'")
                    inString = true;
                if (token is TWhiteSpace)
                {
                    if (token.Text == "\n")
                        inString = false;
                    continue;
                }
                //If this is true, we have an open block comment with no end, so we're in a comment
                if (token is TCommentBegin)
                    return new List<AMethodDecl>();
                //if (token is TArrow)
                //    token = new TDot(".");

                tokens.Add(token);
            }
            if (inString)
            {
                while (!(token is TUnknown && token.Text == "\"" || token.Text == "'"))
                {
                    token = tokens[tokens.Count - 1];
                    tokens.RemoveAt(tokens.Count - 1);
                }
                /*token = tokens[tokens.Count - 1];
                tokens.RemoveAt(tokens.Count - 1);*/
            }
            if (tokens.Count == 0) return new List<AMethodDecl>();
            //The last entered token can either be an identifier, a dot, or a line comment
            token = tokens[tokens.Count - 1];
            tokens.RemoveAt(tokens.Count - 1);
            if (token is TEndOfLineComment)
                return new List<AMethodDecl>();
            //Remove all other comments
            for (int i = 0; i < tokens.Count; i++)
            {
                if (tokens[i] is TTraditionalComment || tokens[i] is TEndOfLineComment || tokens[i] is TDocumentationComment)
                {
                    tokens.RemoveAt(i);
                    i--;
                }
            }

            //Go back untill you encounter a identifier lparen, and count all commas outside of paranthisis or brackets
            //You can stop if you encounter one of ; { }
            commaCount = 0;
            int openParens = 0;

            while (tokens.Count > 0)
            {
                if (token is TLParen)
                {
                    if (openParens > 0)
                    {
                        openParens--;
                    }
                    else
                    {
                        parenPos = new TextPoint(token.Line - 1, token.Pos - 1);
                        token = tokens[tokens.Count - 1];
                        tokens.RemoveAt(tokens.Count - 1);
                        if (token is TPreloadBank)
                        {
                            return new List<AMethodDecl>(){new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null,
                                                                  new ANamedType(new TIdentifier("void"), null),
                                                                  new TIdentifier("PreloadBank"),
                                                                  new ArrayList
                                                                              {
                                                                                  new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                                                  new ANamedType(
                                                                                                      new TIdentifier(
                                                                                                          "string"),
                                                                                                      null),
                                                                                                  new TIdentifier(
                                                                                                      "bankName"), null),
                                                                                  new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                                                  new ANamedType(
                                                                                                      new TIdentifier(
                                                                                                          "int"), null),
                                                                                                  new TIdentifier(
                                                                                                      "player"), null)
                                                                              },
                                                                  null)};
                        }
                        if (token is TGt)
                        {//Check for invoke<...>
                            int pos = tokens.Count - 1;
                            if (tokens[pos] is TIdentifier)
                            {
                                pos--;
                                if (tokens[pos] is TDot && tokens[pos - 1] is TIdentifier)
                                {
                                    pos -= 2;
                                }
                                if (tokens[pos] is TLt)
                                {
                                    pos--;
                                    if (tokens[pos] is TSyncInvoke || tokens[pos] is TAsyncInvoke)
                                    {
                                        isAsyncInvoke = tokens[pos - 1] is TAsyncInvoke;

                                        token = tokens[tokens.Count - 1];
                                        tokens.RemoveAt(tokens.Count - 1);
                                    }
                                }
                            }
                        }
                        //Check for new exp
                        {
                            int parens = 0;
                            for (int i = tokens.Count - 1; i >= 0; i--)
                            {
                                if (tokens[i] is TRParen || tokens[i] is TRBracket)
                                    parens++;
                                else if (tokens[i] is TLParen || tokens[i] is TLBracket)
                                    parens--;
                                else if (parens > 0)
                                    continue;
                                else if (parens < 0)
                                    break;
                                else if (tokens[i] is TSemicolon || tokens[i] is TRBrace || tokens[i] is TLBrace)
                                    break;
                                else if (tokens[i] is TNew)
                                {
                                    string txt = "";
                                    for (int j = 0; j < tokens.Count; j++)
                                    {
                                        txt += tokens[j].Text + " ";
                                    }
                                    txt += token.Text + ".";
                                    List<StructDescription> targetStructs;
                                    List<EnrichmentDescription> targetEnrichments;
                                    List<NamespaceDescription> targetNamespaces;
                                    List<MethodDescription> delegateTargets;
                                    bool b;
                                    List<StructDescription> l;

                                    ExtractTargetType(txt, out targetStructs, out targetEnrichments, out targetNamespaces,
                                                        out b, out l, out b, out delegateTargets, out b);

                                    List<AMethodDecl> methods = new List<AMethodDecl>();
                                    foreach (StructDescription targetStruct in targetStructs)
                                    {
                                        foreach (MethodDescription constructor in targetStruct.Constructors)
                                        {
                                            methods.Add(constructor.Decl);
                                        }
                                    }

                                    foreach (EnrichmentDescription enrichment in targetEnrichments)
                                    {
                                        foreach (MethodDescription constructor in enrichment.Constructors)
                                        {
                                            methods.Add(constructor.Decl);
                                        }
                                    }

                                    return methods;
                                }
                            }
                        }
                        if (token is TIdentifier)
                        {
                            List<AMethodDecl> methods = new List<AMethodDecl>();
                            string methodName = token.Text;
                            if (tokens.Count == 0)
                                return new List<AMethodDecl>();
                            token = tokens[tokens.Count - 1];
                            tokens.RemoveAt(tokens.Count - 1);
                            //If we are in a method decl, we dont want to show anything
                            if (token is TIdentifier || token is TVoid)
                                return new List<AMethodDecl>();
                            bool isGlobal = false;
                            if (token is TDot || token is TArrow)
                            {//It is a struct method.. fetch the method
                                //bool b1, b2, b3;
                                //string namespacePrefix;
                                //MethodDescription delegateTarget;
                                //StructDescription target = GetTargetStruct(token, tokens, out isGlobal, out b1, out namespacePrefix, out b2, out delegateTarget, out b3);

                                string strText = "";
                                {
                                    int parens = 0;
                                    for (int i = text.Length - 1; i >= 0; i--)
                                    {
                                        if (parens == -1)
                                        {
                                            if (text[i] == '.')
                                            {
                                                strText = text.Substring(0, i + 1);
                                                break;
                                            }
                                            if (text.Substring(i, 2) == "->")
                                            {
                                                strText = text.Substring(0, i + 2);
                                                break;
                                            }
                                        }
                                        if (parens < -1)
                                            return new List<AMethodDecl>();
                                        if (text[i] == ')')
                                            parens++;
                                        if (text[i] == '(')
                                            parens--;
                                    }
                                }
                                List<StructDescription> targetStructs;
                                List<EnrichmentDescription> targetEnrichments;
                                List<NamespaceDescription> targetNamespaces;
                                List<MethodDescription> delegateTargets;
                                bool b;
                                bool dynamicArray;
                                List<StructDescription> l;
                                ExtractTargetType(strText, out targetStructs, out targetEnrichments, out targetNamespaces,
                                                    out b, out l, out b, out delegateTargets, out dynamicArray);

                                if (dynamicArray && methodName == "Resize")
                                {
                                    methods.Add(new AMethodDecl(new APublicVisibilityModifier(), null, null, null,
                                                                    null, null, new AVoidType(new TVoid("void")),
                                                                    new TIdentifier("Resize"),
                                                                    new ArrayList()
                                                                        {
                                                                            new AALocalDecl(
                                                                                new APublicVisibilityModifier(), null,
                                                                                null, null, null,
                                                                                new ANamedType(
                                                                                    new TIdentifier("int"), null),
                                                                                new TIdentifier("size"), null)
                                                                        },
                                                                    new AABlock(new ArrayList(), new TRBrace("}"))));
                                }
                                foreach (StructDescription str in targetStructs)
                                {
                                    StructDescription targetStruct = str;
                                    StructDescription initTarget = str;
                                    while (targetStruct != null)
                                    {
                                        foreach (MethodDescription method in targetStruct.Methods)
                                        {
                                            if (!method.IsDelegate && method.Name == methodName)
                                                methods.Add(method.Decl);
                                        }
                                        targetStruct = targetStruct.Base;
                                        if (targetStruct == initTarget)
                                            break;
                                    }
                                }

                                foreach (EnrichmentDescription enrichment in targetEnrichments)
                                {
                                    foreach (MethodDescription method in enrichment.Methods)
                                    {
                                        if (!method.IsDelegate && method.Name == methodName)
                                            methods.Add(method.Decl);
                                    }
                                }
                                foreach (MethodDescription method in delegateTargets)
                                {
                                    methods.Add(method.Decl);
                                }

                                //Go back past all dot identifier, and see if you find a new

                                if (targetNamespaces.Count > 0)
                                {
                                    bool foundNewToken = false;
                                    while (tokens.Count > 0)
                                    {
                                        token = tokens[tokens.Count - 1];
                                        tokens.RemoveAt(tokens.Count - 1);

                                        if (token is TIdentifier || token is TDot)
                                            continue;

                                        if (token is TNew)
                                            foundNewToken = true;
                                        break;
                                    }

                                    if (foundNewToken)
                                    {
                                        foreach (NamespaceDescription ns in targetNamespaces)
                                        {
                                            foreach (StructDescription str in ns.Structs)
                                            {
                                                if (str.Name == methodName)
                                                {
                                                    foreach (MethodDescription method in str.Constructors)
                                                    {
                                                        methods.Add(method.Decl);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        foreach (NamespaceDescription ns in targetNamespaces)
                                        {
                                            foreach (MethodDescription method in ns.Methods)
                                            {
                                                if (!method.IsDelegate && method.Name == methodName)
                                                    methods.Add(method.Decl);
                                            }
                                        }
                                    }
                                }
                                if (!isGlobal || methods.Count > 0)
                                    return methods;
                            }
                            if (token is TNew)
                            {//Find matching constructors
                                foreach (SourceFileContents file in Compiler.ParsedSourceFiles)
                                {
                                    foreach (StructDescription str in file.Structs)
                                    {
                                        if (str.Name == methodName)
                                        {
                                            foreach (MethodDescription constructor in str.Constructors)
                                            {
                                                methods.Add(constructor.Decl);
                                            }
                                            return methods;
                                        }
                                    }
                                }

                            }

                            object openFileData = currentEditor.Tag is Form1.OpenFileData
                                                      ? ((Form1.OpenFileData)currentEditor.Tag).File
                                                      : (object)((DialogData)currentEditor.Tag).DialogItem;
                            SourceFileContents currentSourceFile = null;
                            foreach (SourceFileContents sourceFileContents in Compiler.ParsedSourceFiles)
                            {
                                if (openFileData == sourceFileContents.Item && !sourceFileContents.IsDialogDesigner)
                                {
                                    currentSourceFile = sourceFileContents;
                                    break;
                                }
                            }
                            if (currentSourceFile == null)
                                return new List<AMethodDecl>();
                            if (!isGlobal)
                            {
                                //Current struct
                                int line = CurrentEditor.caret.Position.Line;
                                foreach (StructDescription structDescription in currentSourceFile.Structs)
                                {
                                    if (structDescription.LineFrom <= line && line <= structDescription.LineTo)
                                    {
                                        StructDescription target = structDescription;
                                        StructDescription initTarget = target;
                                        while (target != null)
                                        {
                                            foreach (MethodDescription method in structDescription.Methods)
                                            {
                                                if (!method.IsDelegate && method.Name == methodName)
                                                    methods.Add(method.Decl);
                                            }
                                            target = target.Base;
                                            if (target == initTarget)
                                                break;
                                        }
                                    }
                                }
                                //Current enrichment
                                foreach (EnrichmentDescription enrichment in currentSourceFile.Enrichments)
                                {
                                    if (enrichment.LineFrom <= line && line <= enrichment.LineTo)
                                    {
                                        foreach (MethodDescription method in enrichment.Methods)
                                        {
                                            if (!method.IsDelegate && method.Name == methodName)
                                                methods.Add(method.Decl);
                                        }
                                    }
                                }
                            }
                            if (methods.Count == 0)
                            {
                                //It is a global method
                                foreach (SourceFileContents sourceFile in Compiler.ParsedSourceFiles)
                                {
                                    /*if (!currentSourceFile.CanSeeOther(sourceFile))
                                        continue;*/

                                    foreach (MethodDescription method in sourceFile.Methods)
                                    {
                                        if (method.Visibility is APrivateVisibilityModifier &&
                                            sourceFile.Namespace != currentSourceFile.Namespace)
                                            continue;

                                        if (!method.IsDelegate && method.Name == methodName)
                                            methods.Add(method.Decl);
                                    }
                                }
                                foreach (AMethodDecl method in Compiler.libraryData.Methods)
                                {
                                    if (method.GetName().Text == methodName)
                                        methods.Add(method);
                                }
                            }
                            return methods;
                        }
                        else
                        {
                            commaCount = 0;
                            continue;
                        }
                    }
                }
                if (token is TRParen || token is TRBracket)
                    openParens++;
                if (token is TLBracket)
                {
                    if (openParens > 0)
                        openParens--;
                    else
                        commaCount = 0;
                }
                if (token is TComma && openParens == 0)
                    commaCount++;
                if (token is TSemicolon || token is TLBrace || token is TRBrace)
                    return new List<AMethodDecl>();
                token = tokens[tokens.Count - 1];
                tokens.RemoveAt(tokens.Count - 1);
            }
            return new List<AMethodDecl>();
        }