// This file was generated automatically by the Snowball to JSX compiler

import "base-stemmer.jsx";
import "among.jsx";

 /**
  * This class was automatically generated by a Snowball to JSX compiler
  * It implements the stemming algorithm defined by a snowball script.
  */

class GermanStemmer extends BaseStemmer
{
    static const serialVersionUID = 1;
    static const methodObject = new GermanStemmer();

    static const a_0 = [
        new Among("", -1, 6),
        new Among("U", 0, 2),
        new Among("Y", 0, 1),
        new Among("\u00E4", 0, 3),
        new Among("\u00F6", 0, 4),
        new Among("\u00FC", 0, 5)
    ];

    static const a_1 = [
        new Among("e", -1, 2),
        new Among("em", -1, 1),
        new Among("en", -1, 2),
        new Among("ern", -1, 1),
        new Among("er", -1, 1),
        new Among("s", -1, 3),
        new Among("es", 5, 2)
    ];

    static const a_2 = [
        new Among("en", -1, 1),
        new Among("er", -1, 1),
        new Among("st", -1, 2),
        new Among("est", 2, 1)
    ];

    static const a_3 = [
        new Among("ig", -1, 1),
        new Among("lich", -1, 1)
    ];

    static const a_4 = [
        new Among("end", -1, 1),
        new Among("ig", -1, 2),
        new Among("ung", -1, 1),
        new Among("lich", -1, 3),
        new Among("isch", -1, 2),
        new Among("ik", -1, 2),
        new Among("heit", -1, 3),
        new Among("keit", -1, 4)
    ];

    static const g_v = [17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 8] : int[];

    static const g_s_ending = [117, 30, 5] : int[];

    static const g_st_ending = [117, 30, 4] : int[];

    var I_x : int = 0;
    var I_p2 : int = 0;
    var I_p1 : int = 0;

    function copy_from (other : GermanStemmer) : void
    {
        this.I_x = other.I_x;
        this.I_p2 = other.I_p2;
        this.I_p1 = other.I_p1;
        super.copy_from(other);
    }

    function r_prelude () : boolean
    {
        var v_1 : int;
        var v_2 : int;
        var v_3 : int;
        var v_4 : int;
        var v_5 : int;
        var v_6 : int;
        // (, line 33
        // test, line 35
        v_1 = this.cursor;
        // repeat, line 35
        replab0: while(true)
        {
            v_2 = this.cursor;
            var lab1 = true;
            lab1: while (lab1 == true)
            {
                lab1 = false;
                // (, line 35
                // or, line 38
                var lab2 = true;
                lab2: while (lab2 == true)
                {
                    lab2 = false;
                    v_3 = this.cursor;
                    var lab3 = true;
                    lab3: while (lab3 == true)
                    {
                        lab3 = false;
                        // (, line 36
                        // [, line 37
                        this.bra = this.cursor;
                        // literal, line 37
                        if (!(this.eq_s(1, "\u00DF")))
                        {
                            break lab3;
                        }
                        // ], line 37
                        this.ket = this.cursor;
                        // <-, line 37
                        if (!this.slice_from("ss"))
                        {
                            return false;
                        }
                        break lab2;
                    }
                    this.cursor = v_3;
                    // next, line 38
                    if (this.cursor >= this.limit)
                    {
                        break lab1;
                    }
                    this.cursor++;
                }
                continue replab0;
            }
            this.cursor = v_2;
            break replab0;
        }
        this.cursor = v_1;
        // repeat, line 41
        replab4: while(true)
        {
            v_4 = this.cursor;
            var lab5 = true;
            lab5: while (lab5 == true)
            {
                lab5 = false;
                // goto, line 41
                golab6: while(true)
                {
                    v_5 = this.cursor;
                    var lab7 = true;
                    lab7: while (lab7 == true)
                    {
                        lab7 = false;
                        // (, line 41
                        if (!(this.in_grouping(GermanStemmer.g_v, 97, 252)))
                        {
                            break lab7;
                        }
                        // [, line 42
                        this.bra = this.cursor;
                        // or, line 42
                        var lab8 = true;
                        lab8: while (lab8 == true)
                        {
                            lab8 = false;
                            v_6 = this.cursor;
                            var lab9 = true;
                            lab9: while (lab9 == true)
                            {
                                lab9 = false;
                                // (, line 42
                                // literal, line 42
                                if (!(this.eq_s(1, "u")))
                                {
                                    break lab9;
                                }
                                // ], line 42
                                this.ket = this.cursor;
                                if (!(this.in_grouping(GermanStemmer.g_v, 97, 252)))
                                {
                                    break lab9;
                                }
                                // <-, line 42
                                if (!this.slice_from("U"))
                                {
                                    return false;
                                }
                                break lab8;
                            }
                            this.cursor = v_6;
                            // (, line 43
                            // literal, line 43
                            if (!(this.eq_s(1, "y")))
                            {
                                break lab7;
                            }
                            // ], line 43
                            this.ket = this.cursor;
                            if (!(this.in_grouping(GermanStemmer.g_v, 97, 252)))
                            {
                                break lab7;
                            }
                            // <-, line 43
                            if (!this.slice_from("Y"))
                            {
                                return false;
                            }
                        }
                        this.cursor = v_5;
                        break golab6;
                    }
                    this.cursor = v_5;
                    if (this.cursor >= this.limit)
                    {
                        break lab5;
                    }
                    this.cursor++;
                }
                continue replab4;
            }
            this.cursor = v_4;
            break replab4;
        }
        return true;
    }

    function r_mark_regions () : boolean
    {
        var v_1 : int;
        // (, line 47
        this.I_p1 = this.limit;
        this.I_p2 = this.limit;
        // test, line 52
        v_1 = this.cursor;
        // (, line 52
        // hop, line 52
        {
            var c : int = this.cursor + 3;
            if (0 > c || c > this.limit)
            {
                return false;
            }
            this.cursor = c;
        }
        // setmark x, line 52
        this.I_x = this.cursor;
        this.cursor = v_1;
        // gopast, line 54
        golab0: while(true)
        {
            var lab1 = true;
            lab1: while (lab1 == true)
            {
                lab1 = false;
                if (!(this.in_grouping(GermanStemmer.g_v, 97, 252)))
                {
                    break lab1;
                }
                break golab0;
            }
            if (this.cursor >= this.limit)
            {
                return false;
            }
            this.cursor++;
        }
        // gopast, line 54
        golab2: while(true)
        {
            var lab3 = true;
            lab3: while (lab3 == true)
            {
                lab3 = false;
                if (!(this.out_grouping(GermanStemmer.g_v, 97, 252)))
                {
                    break lab3;
                }
                break golab2;
            }
            if (this.cursor >= this.limit)
            {
                return false;
            }
            this.cursor++;
        }
        // setmark p1, line 54
        this.I_p1 = this.cursor;
        // try, line 55
        var lab4 = true;
        lab4: while (lab4 == true)
        {
            lab4 = false;
            // (, line 55
            if (!(this.I_p1 < this.I_x))
            {
                break lab4;
            }
            this.I_p1 = this.I_x;
        }
        // gopast, line 56
        golab5: while(true)
        {
            var lab6 = true;
            lab6: while (lab6 == true)
            {
                lab6 = false;
                if (!(this.in_grouping(GermanStemmer.g_v, 97, 252)))
                {
                    break lab6;
                }
                break golab5;
            }
            if (this.cursor >= this.limit)
            {
                return false;
            }
            this.cursor++;
        }
        // gopast, line 56
        golab7: while(true)
        {
            var lab8 = true;
            lab8: while (lab8 == true)
            {
                lab8 = false;
                if (!(this.out_grouping(GermanStemmer.g_v, 97, 252)))
                {
                    break lab8;
                }
                break golab7;
            }
            if (this.cursor >= this.limit)
            {
                return false;
            }
            this.cursor++;
        }
        // setmark p2, line 56
        this.I_p2 = this.cursor;
        return true;
    }

    function r_postlude () : boolean
    {
        var among_var : int;
        var v_1 : int;
        // repeat, line 60
        replab0: while(true)
        {
            v_1 = this.cursor;
            var lab1 = true;
            lab1: while (lab1 == true)
            {
                lab1 = false;
                // (, line 60
                // [, line 62
                this.bra = this.cursor;
                // substring, line 62
                among_var = this.find_among(GermanStemmer.a_0, 6);
                if (among_var == 0)
                {
                    break lab1;
                }
                // ], line 62
                this.ket = this.cursor;
                switch (among_var) {
                    case 0:
                        break lab1;
                    case 1:
                        // (, line 63
                        // <-, line 63
                        if (!this.slice_from("y"))
                        {
                            return false;
                        }
                        break;
                    case 2:
                        // (, line 64
                        // <-, line 64
                        if (!this.slice_from("u"))
                        {
                            return false;
                        }
                        break;
                    case 3:
                        // (, line 65
                        // <-, line 65
                        if (!this.slice_from("a"))
                        {
                            return false;
                        }
                        break;
                    case 4:
                        // (, line 66
                        // <-, line 66
                        if (!this.slice_from("o"))
                        {
                            return false;
                        }
                        break;
                    case 5:
                        // (, line 67
                        // <-, line 67
                        if (!this.slice_from("u"))
                        {
                            return false;
                        }
                        break;
                    case 6:
                        // (, line 68
                        // next, line 68
                        if (this.cursor >= this.limit)
                        {
                            break lab1;
                        }
                        this.cursor++;
                        break;
                }
                continue replab0;
            }
            this.cursor = v_1;
            break replab0;
        }
        return true;
    }

    function r_R1 () : boolean
    {
        if (!(this.I_p1 <= this.cursor))
        {
            return false;
        }
        return true;
    }

    function r_R2 () : boolean
    {
        if (!(this.I_p2 <= this.cursor))
        {
            return false;
        }
        return true;
    }

    function r_standard_suffix () : boolean
    {
        var among_var : int;
        var v_1 : int;
        var v_2 : int;
        var v_3 : int;
        var v_4 : int;
        var v_5 : int;
        var v_6 : int;
        var v_7 : int;
        var v_8 : int;
        var v_9 : int;
        var v_10 : int;
        // (, line 78
        // do, line 79
        v_1 = this.limit - this.cursor;
        var lab0 = true;
        lab0: while (lab0 == true)
        {
            lab0 = false;
            // (, line 79
            // [, line 80
            this.ket = this.cursor;
            // substring, line 80
            among_var = this.find_among_b(GermanStemmer.a_1, 7);
            if (among_var == 0)
            {
                break lab0;
            }
            // ], line 80
            this.bra = this.cursor;
            // call R1, line 80
            if (!this.r_R1())
            {
                break lab0;
            }
            switch (among_var) {
                case 0:
                    break lab0;
                case 1:
                    // (, line 82
                    // delete, line 82
                    if (!this.slice_del())
                    {
                        return false;
                    }
                    break;
                case 2:
                    // (, line 85
                    // delete, line 85
                    if (!this.slice_del())
                    {
                        return false;
                    }
                    // try, line 86
                    v_2 = this.limit - this.cursor;
                    var lab1 = true;
                    lab1: while (lab1 == true)
                    {
                        lab1 = false;
                        // (, line 86
                        // [, line 86
                        this.ket = this.cursor;
                        // literal, line 86
                        if (!(this.eq_s_b(1, "s")))
                        {
                            this.cursor = this.limit - v_2;
                            break lab1;
                        }
                        // ], line 86
                        this.bra = this.cursor;
                        // literal, line 86
                        if (!(this.eq_s_b(3, "nis")))
                        {
                            this.cursor = this.limit - v_2;
                            break lab1;
                        }
                        // delete, line 86
                        if (!this.slice_del())
                        {
                            return false;
                        }
                    }
                    break;
                case 3:
                    // (, line 89
                    if (!(this.in_grouping_b(GermanStemmer.g_s_ending, 98, 116)))
                    {
                        break lab0;
                    }
                    // delete, line 89
                    if (!this.slice_del())
                    {
                        return false;
                    }
                    break;
            }
        }
        this.cursor = this.limit - v_1;
        // do, line 93
        v_3 = this.limit - this.cursor;
        var lab2 = true;
        lab2: while (lab2 == true)
        {
            lab2 = false;
            // (, line 93
            // [, line 94
            this.ket = this.cursor;
            // substring, line 94
            among_var = this.find_among_b(GermanStemmer.a_2, 4);
            if (among_var == 0)
            {
                break lab2;
            }
            // ], line 94
            this.bra = this.cursor;
            // call R1, line 94
            if (!this.r_R1())
            {
                break lab2;
            }
            switch (among_var) {
                case 0:
                    break lab2;
                case 1:
                    // (, line 96
                    // delete, line 96
                    if (!this.slice_del())
                    {
                        return false;
                    }
                    break;
                case 2:
                    // (, line 99
                    if (!(this.in_grouping_b(GermanStemmer.g_st_ending, 98, 116)))
                    {
                        break lab2;
                    }
                    // hop, line 99
                    {
                        var c : int = this.cursor - 3;
                        if (this.limit_backward > c || c > this.limit)
                        {
                            break lab2;
                        }
                        this.cursor = c;
                    }
                    // delete, line 99
                    if (!this.slice_del())
                    {
                        return false;
                    }
                    break;
            }
        }
        this.cursor = this.limit - v_3;
        // do, line 103
        v_4 = this.limit - this.cursor;
        var lab3 = true;
        lab3: while (lab3 == true)
        {
            lab3 = false;
            // (, line 103
            // [, line 104
            this.ket = this.cursor;
            // substring, line 104
            among_var = this.find_among_b(GermanStemmer.a_4, 8);
            if (among_var == 0)
            {
                break lab3;
            }
            // ], line 104
            this.bra = this.cursor;
            // call R2, line 104
            if (!this.r_R2())
            {
                break lab3;
            }
            switch (among_var) {
                case 0:
                    break lab3;
                case 1:
                    // (, line 106
                    // delete, line 106
                    if (!this.slice_del())
                    {
                        return false;
                    }
                    // try, line 107
                    v_5 = this.limit - this.cursor;
                    var lab4 = true;
                    lab4: while (lab4 == true)
                    {
                        lab4 = false;
                        // (, line 107
                        // [, line 107
                        this.ket = this.cursor;
                        // literal, line 107
                        if (!(this.eq_s_b(2, "ig")))
                        {
                            this.cursor = this.limit - v_5;
                            break lab4;
                        }
                        // ], line 107
                        this.bra = this.cursor;
                        // not, line 107
                        {
                            v_6 = this.limit - this.cursor;
                            var lab5 = true;
                            lab5: while (lab5 == true)
                            {
                                lab5 = false;
                                // literal, line 107
                                if (!(this.eq_s_b(1, "e")))
                                {
                                    break lab5;
                                }
                                this.cursor = this.limit - v_5;
                                break lab4;
                            }
                            this.cursor = this.limit - v_6;
                        }
                        // call R2, line 107
                        if (!this.r_R2())
                        {
                            this.cursor = this.limit - v_5;
                            break lab4;
                        }
                        // delete, line 107
                        if (!this.slice_del())
                        {
                            return false;
                        }
                    }
                    break;
                case 2:
                    // (, line 110
                    // not, line 110
                    {
                        v_7 = this.limit - this.cursor;
                        var lab6 = true;
                        lab6: while (lab6 == true)
                        {
                            lab6 = false;
                            // literal, line 110
                            if (!(this.eq_s_b(1, "e")))
                            {
                                break lab6;
                            }
                            break lab3;
                        }
                        this.cursor = this.limit - v_7;
                    }
                    // delete, line 110
                    if (!this.slice_del())
                    {
                        return false;
                    }
                    break;
                case 3:
                    // (, line 113
                    // delete, line 113
                    if (!this.slice_del())
                    {
                        return false;
                    }
                    // try, line 114
                    v_8 = this.limit - this.cursor;
                    var lab7 = true;
                    lab7: while (lab7 == true)
                    {
                        lab7 = false;
                        // (, line 114
                        // [, line 115
                        this.ket = this.cursor;
                        // or, line 115
                        var lab8 = true;
                        lab8: while (lab8 == true)
                        {
                            lab8 = false;
                            v_9 = this.limit - this.cursor;
                            var lab9 = true;
                            lab9: while (lab9 == true)
                            {
                                lab9 = false;
                                // literal, line 115
                                if (!(this.eq_s_b(2, "er")))
                                {
                                    break lab9;
                                }
                                break lab8;
                            }
                            this.cursor = this.limit - v_9;
                            // literal, line 115
                            if (!(this.eq_s_b(2, "en")))
                            {
                                this.cursor = this.limit - v_8;
                                break lab7;
                            }
                        }
                        // ], line 115
                        this.bra = this.cursor;
                        // call R1, line 115
                        if (!this.r_R1())
                        {
                            this.cursor = this.limit - v_8;
                            break lab7;
                        }
                        // delete, line 115
                        if (!this.slice_del())
                        {
                            return false;
                        }
                    }
                    break;
                case 4:
                    // (, line 119
                    // delete, line 119
                    if (!this.slice_del())
                    {
                        return false;
                    }
                    // try, line 120
                    v_10 = this.limit - this.cursor;
                    var lab10 = true;
                    lab10: while (lab10 == true)
                    {
                        lab10 = false;
                        // (, line 120
                        // [, line 121
                        this.ket = this.cursor;
                        // substring, line 121
                        among_var = this.find_among_b(GermanStemmer.a_3, 2);
                        if (among_var == 0)
                        {
                            this.cursor = this.limit - v_10;
                            break lab10;
                        }
                        // ], line 121
                        this.bra = this.cursor;
                        // call R2, line 121
                        if (!this.r_R2())
                        {
                            this.cursor = this.limit - v_10;
                            break lab10;
                        }
                        switch (among_var) {
                            case 0:
                                this.cursor = this.limit - v_10;
                                break lab10;
                            case 1:
                                // (, line 123
                                // delete, line 123
                                if (!this.slice_del())
                                {
                                    return false;
                                }
                                break;
                        }
                    }
                    break;
            }
        }
        this.cursor = this.limit - v_4;
        return true;
    }

    override function stem () : boolean
    {
        var v_1 : int;
        var v_2 : int;
        var v_3 : int;
        var v_4 : int;
        // (, line 133
        // do, line 134
        v_1 = this.cursor;
        var lab0 = true;
        lab0: while (lab0 == true)
        {
            lab0 = false;
            // call prelude, line 134
            if (!this.r_prelude())
            {
                break lab0;
            }
        }
        this.cursor = v_1;
        // do, line 135
        v_2 = this.cursor;
        var lab1 = true;
        lab1: while (lab1 == true)
        {
            lab1 = false;
            // call mark_regions, line 135
            if (!this.r_mark_regions())
            {
                break lab1;
            }
        }
        this.cursor = v_2;
        // backwards, line 136
        this.limit_backward = this.cursor; this.cursor = this.limit;
        // do, line 137
        v_3 = this.limit - this.cursor;
        var lab2 = true;
        lab2: while (lab2 == true)
        {
            lab2 = false;
            // call standard_suffix, line 137
            if (!this.r_standard_suffix())
            {
                break lab2;
            }
        }
        this.cursor = this.limit - v_3;
        this.cursor = this.limit_backward;        // do, line 138
        v_4 = this.cursor;
        var lab3 = true;
        lab3: while (lab3 == true)
        {
            lab3 = false;
            // call postlude, line 138
            if (!this.r_postlude())
            {
                break lab3;
            }
        }
        this.cursor = v_4;
        return true;
    }

    function equals (o : variant) : boolean {
        return o instanceof GermanStemmer;
    }

    function hashCode() : int
    {
        //http://stackoverflow.com/questions/194846/is-there-any-kind-of-hashcode-function-in-javascript
        var classname = "GermanStemmer";
        var hash = 0;
        if (classname.length == 0) return hash;
        for (var i = 0; i < classname.length; i++) {
            var char = classname.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash; // Convert to 32bit integer
        }
        return hash;
    }

}

