import java.util.*;
import java.awt.Color;
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Verwaltet die Hintergründe (Maps) und das Scrollen.
 * 
 * @author Florian
 */
public class Background extends UI
{
    public static int current = -1;         //ID der aktuellen Map
    public static GreenfootImage img;       //Bild der Map
    public static GreenfootImage mask;      //Maske der Map
    public static int left;     //Code der Map links    
    public static int right;    //Code der Map rechts
    public static int up;       //Code der Map oben
    public static int down;     //Code der Map unten
    public static int originDir;    //Richtung von der man in die Fehlermap gekommen ist
    public static int originCode;   //Code der Map von der man in die Fehlermap gekommen ist
    public static boolean fail;     //True wenn man in einer Fehlermap ist
    public static List<OH> obj = new ArrayList<OH>();       //Objekte der Map
    public static World w;
    public static String[] falschAbgebogen = {"Du bist leider falsch abgebogen!", "Nach einem kleinem Umweg kommst du wieder zurück!", "", "TIPP: Laufe solage nach oben bis es nicht", "mehr weitergeht und suche dann den Ausgang."};
    public static boolean useSW = false;
    /**
     * Ändert den Stil der Maps von Farbe zu Schwarz Weiß und anders herum
     */
    public static void changeStil(){
        useSW = !useSW;
        if(useSW){
            img = new GreenfootImage("Maps/sw/" + current +".png");
        }else{
            img = new GreenfootImage("Maps/" + current +".png");
        }
        img.scale(Welt.width, Welt.height);
        w.setBackground(img);
    }

    /**
     * Ändert die aktuelle Map. 
     * 
     * @param id ID der neuen Map
     * @author Florian
     */
    public static void setCurrent(int id){
        obj.clear();
        current = id;
        if(useSW){
            img = new GreenfootImage("Maps/sw/" + id +".png");
        }else{
            img = new GreenfootImage("Maps/" + id +".png");
        }
        mask = new GreenfootImage("Maps/Mask/" + id + ".png");
        switch(id){
            case 10:{
                left = 0;
                right = 0;
                up = 11;
                down = 0;
                obj.add(new OH(new Fire(), 400,200));    
                obj.add(new OH(new Guenther(), 400, 300));
                break;
            }case 11:{
                left = 0;
                right = 0;
                up = 12;
                down = 10;
                
                obj.add(new OH(new Bottlecheck(), 389, 198));
                obj.add(new OH(new Bottlecheck(), 235, 350));
                obj.add(new OH(new Bottlecheck(), 90, 80));
                break;
            }case 12:{
                left = 0;
                right = 0;
                up = 20;
                down = 11;
                obj.add(randomSpawn(new MonsterLevel_1()));
                
                break;
            }case 20:{
                left = 0;
                right = 0;
                up = 21;
                down = 12;

                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                break;
            }case 21:{
                left = 22;
                right = 120;
                up = 20;
                down = 0;
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                break;
            }case 22:{
                left = 23;
                right = 21;
                up = 0;
                down = 0;
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_2()));
                break;
            }case 23:{
                left = 0;
                right = 22;
                up = 24;
                down = 0;
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new Asprin()));
                break;
            }case 24:{
                left = 25;
                right = 0;
                up = 120;
                down = 23;
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(new OH(new Bombcheck(), 400,400));
                break;
            }case 25:{
                left = 0;
                right = 24;
                up = 26;
                down = 0;
                obj.add(randomSpawn(new MonsterLevel_1()));
                
                break;
            }case 26:{
                left = 120;
                right = 0;
                up = 27;
                down = 25;
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                break;
            }case 27:{
                left = 0;
                right = 120;
                up = 30;
                down = 26;
                obj.add(randomSpawn(new MonsterLevel_2()));
                break;
            }case 30:{
                left = 130;
                right = 31;
                up = 0;
                down = 0;
                obj.add(randomSpawn(new Asprin()));
				obj.add(randomSpawn(new MonsterLevel_3()));
				obj.add(new OH(new throw_bottlecheck(), 320, 380));
                break;
            }case 31:{
                left = 30;
                right = 0;
                up = 32;
                down = 0;
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_2()));
                break;
            }case 32:{
                left = 0;
                right = 0;
                up = 33;
                down = 31;
                break;
            }case 33:{
                left = 0;
                right = 34;
                up = 130;
                down = 32;
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                break;
            }case 34:{
                left = 33;
                right = 0;
                up = 35;
                down = 0;
                break;
            }case 35:{
                left = 130;
                right = 36;
                up = 0;
                down = 34;
                 obj.add(randomSpawn(new MonsterLevel_1()));
                break;
            }case 36:{
                left = 35;
                right = 37;
                up = 0;
                down = 0;
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                break;
            }case 37:{
                left = 36;
                right = 40;
                up = 130;
                down = 0;
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_2()));
                break;
            }case 40:{
                left = 0;
                right = 0;
                up = 0;
                down = 41;
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                break;
            }            
            case 41:{
                left = 140;
                right = 42;
                up = 40;
                down = 0;
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_2()));
                break;
            }case 42:{
                left = 41;
                right = 0;
                up = 43;
                down = 0;
                obj.add(randomSpawn(new Asprin()));
                obj.add(randomSpawn(new Asprin()));
                break;
            }case 43:{
                left = 0;
                right = 0;
                up = 44;
                down = 42;
                break;
            }            
            case 44:{
                left = 140;
                right = 0;
                up = 45;
                down = 33;
                 obj.add(randomSpawn(new MonsterLevel_1()));
                obj.add(randomSpawn(new MonsterLevel_2()));
                obj.add(randomSpawn(new MonsterLevel_1()));
                break;
            }case 45:{
                left = 0;
                right = 46;
                up = 140;
                down = 44;
                break;
            }case 46:{
                left = 45;
                right = 47;
                up = 0;
                down = 0;
				obj.add(randomSpawn(new MonsterLevel_3()));
                break;
            }case 47:{
                left = 46;
                right = 48;
                up = 0;
                down = 0;
                break;
            }case 48:{
                left = 47;
                right = 50;
                up = 140;
                down = 0;
				obj.add(randomSpawn(new MonsterLevel_1()));
				obj.add(randomSpawn(new MonsterLevel_3()));
                break;
            }case 50:{
                left = 48;
                right = 140;
                up = 51;
                down = 0;
                obj.add(new OH(new Monsterboss(), 320, 240));
                break;
            }case 51:{
                left = 0;
                right = 0;
                up = 0;
                down = 0;
                String[] msg = {"Glückwunsch!", "", "Du hast es bis zum deinem Haus geschafft!"};
                Background.msg(msg);
                Greenfoot.playSound("winning.mp3");
                break;
            }case 190:{
                left = 0;
                right = 0;
                down = 0;
                up = 191;
                break;
            }case 191:{
                left = -1;
                right = -1;
                down = 0;
                up = -1;
                break;
            }case 120:{
                left = 0;
                right = 0;
                down = 0;
                up = 121;
                break;
            }case 121:{
                left = 0;
                right = 0;
                down = 0;
                up = 122;
                break;
            }case 122:{
                left = -1;
                right = -1;
                down = 0;
                up = -1;
                break;
            }case 130:{
                left = 0;
                right = 0;
                down = 0;
                up = 131;
                break;
            }case 131:{
                left = 0;
                right = 0;
                down = 0;
                up = 132;
                break;
            }case 132:{
                left = 0;
                right = 0;
                down = 0;
                up = 133;
                break;
            }case 133:{
                left = -1;
                right = -1;
                    down = 0;
                up = -1;
                break;
            }case 140:{
                left = 0;
                right = 0;
                down = 0;
                up = 141;
                break;
            }case 141:{
                left = 0;
                right = 0;
                down = 0;
                up = 142;
                break;
            }case 142:{
                left = 0;
                right = 0;
                down = 0;
                up = 143;
                break;
            }case 143:{
                left = 0;
                right = 0;
                down = 0;
                up = 144;
                break;
            }case 144:{
                left = -1;
                right = -1;
                down = 0;
                up = -1;
                break;
            }

        }

        img.scale(Welt.width, Welt.height);
        mask.scale(Welt.width, Welt.height);

    }
    /**
     * Spawnt den Actor an einer zufälligen Stelle im Bild wo die Maske es zulässt
     * 
     * @param elem Actor der in die Welt gesetzt werden soll
     * @author Florian
     */
    public static OH randomSpawn(Actor elem){
        int x, y;
        do{
            x = Greenfoot.getRandomNumber(Welt.width);
            y = Greenfoot.getRandomNumber(Welt.height);
        }while(Background.mask.getColorAt(x, y).equals(Color.black));  //Actor darf an diese Stelle
        return new OH(elem, x, y);        
    }

    /**
     * Zeigt eine Nachricht an, pausiert alle Elemente bis in der Nachricht auf "OK" geklickt wurde
     * 
     * @param text  Array aus Strings die anzuzeigen sind
     * @author Florian
     */
    public static void msg(String[] text){
        Message msg = new Message(text);
        Button btn = new Button("okay", 0,0,0);
        w.addObject(msg, 320, 240);
        msg.show();
        w.addObject(btn, 460, 360);
        btn.run();
    }

    /**
     * Prüft, ob Linch an den Rand der Map gekommen ist und scrollt bei Bedarf in die Nächste Map
     * 
     * @param linch Linch
     * @param w Welt
     * @author Florian
     */
    public static void check(Actor linch, Welt w){
        w=w;
        int marginResult = checkMargin(linch, w);
        int width = w.width;
        int height = w.height;
        int step = w.step;
        if(marginResult == 1){     //Linker Rand
            if(Background.left != 0){

                if(Background.left >= 100 && !Background.fail){
                    Background.originDir = marginResult;
                    Background.originCode = Background.current;
                    Background.fail = true;

                    Background.msg(falschAbgebogen);
                }
                if(Background.left == -1){
                    if(Background.originDir == 2){
                        Background.left = Background.originCode;
                        Background.fail = false;
                    }else{
                        return;
                    }
                }
                Background.setCurrent(Background.left);
                GreenfootImage img = new GreenfootImage(2*width, height);
                img.drawImage(Background.img, 0, 0);
                img.drawImage(w.getBackground(), width, 0);

                List<Element> oldObj = w.getObjects(Element.class);
                List<OH> newObj = Background.obj;
                for(OH obj: newObj){
                    w.addObject(obj.obj, -width + obj.x, obj.y);
                }
                List<Element> all = w.getObjects(Element.class);
                for (int i = 0; i <= width; i+=step){
                    GreenfootImage img2 = new GreenfootImage(width, height);
                    img2.drawImage(img, -width+i, 0);
                    w.setBackground(img2);
                    linch.setLocation((width-(w.paddingX+1))*i/width, linch.getY());
                    for(Element e: all){
                        e.setLocation(e.getX()+step, e.getY());
                    }
                    Greenfoot.delay(1);
                }
                w.removeObjects(oldObj);
                w.setBackground(Background.img);
            }
        }
        if(marginResult == 2){     //Rechter Rand
            if(Background.right != 0){
                if(Background.right >= 100 && !Background.fail){
                    Background.originDir = marginResult;
                    Background.originCode = Background.current;
                    Background.fail = true;

                    Background.msg(falschAbgebogen);
                }
                if(Background.right == -1){
                    if(Background.originDir == 1){
                        Background.right = Background.originCode;
                        Background.fail = false;
                    }else{
                        return;
                    }
                }

                Background.setCurrent(Background.right);
                GreenfootImage img = new GreenfootImage(2*width, height);
                img.drawImage(w.getBackground(), 0, 0);
                img.drawImage(Background.img, width, 0);
                List<Element> oldObj = w.getObjects(Element.class);
                List<OH> newObj = Background.obj;
                for(OH obj: newObj){
                    w.addObject(obj.obj, width + obj.x, obj.y);
                }
                List<Element> all = w.getObjects(Element.class);
                for (int i = 0; i <= width; i+=step){
                    GreenfootImage img2 = new GreenfootImage(width, height);
                    img2.drawImage(img, -i, 0);
                    w.setBackground(img2);
                    linch.setLocation(width-i+(w.paddingX+1)*i/width, linch.getY());
                    for(Element e: all){
                        e.setLocation(e.getX()-step, e.getY());
                    }
                    Greenfoot.delay(1);
                }
                w.removeObjects(oldObj);
                w.setBackground(Background.img);

            }
        }
        if(marginResult == 3){     //Oberer Rand
            if(Background.up != 0){
                if(Background.up >= 100 && !Background.fail){
                    Background.originDir = marginResult;
                    Background.originCode = Background.current;
                    Background.fail = true;

                    Background.msg(falschAbgebogen);
                }
                if(Background.up == -1){
                    if(Background.originDir == 4){
                        Background.up = Background.originCode;
                        Background.fail = false;
                    }else{
                        return;
                    }
                }

                Background.setCurrent(Background.up);
                GreenfootImage img = new GreenfootImage(width, height*2);
                img.drawImage(w.getBackground(), 0, height);
                img.drawImage(Background.img, 0, 0);
                List<Element> oldObj = w.getObjects(Element.class);
                List<OH> newObj = Background.obj;
                for(OH obj: newObj){
                    w.addObject(obj.obj, obj.x, -height + obj.y);
                }
                List<Element> all = w.getObjects(Element.class);
                for (int i = 0; i <= height; i+=step){
                    GreenfootImage img2 = new GreenfootImage(width, height);
                    img2.drawImage(img, 0, -height+i);
                    w.setBackground(img2);
                    linch.setLocation(linch.getX(), i-(w.paddingY+1)*i/height);
                    for(Element e: all){
                        e.setLocation(e.getX(), e.getY()+step);
                    }
                    Greenfoot.delay(1);
                }
                w.removeObjects(oldObj);
                w.setBackground(Background.img);

            }
        }
        if(marginResult == 4){     //Unterer Rand
            if(Background.down != 0){
                if(Background.down >= 100 && !Background.fail){
                    Background.originDir = marginResult;
                    Background.originCode = Background.current;
                    Background.fail = true;

                    Background.msg(falschAbgebogen);
                }
                if(Background.down == -1){
                    if(Background.originDir == 3){
                        Background.down = Background.originCode;
                        Background.fail = false;
                    }else{
                        return;
                    }
                }

                Background.setCurrent(Background.down);
                GreenfootImage img = new GreenfootImage(width, height*2);
                img.drawImage(w.getBackground(), 0, 0);
                img.drawImage(Background.img, 0, height);
                List<Element> oldObj = w.getObjects(Element.class);
                List<OH> newObj = Background.obj;
                for(OH obj: newObj){
                    w.addObject(obj.obj, obj.x, height + obj.y);
                }
                List<Element> all = w.getObjects(Element.class);
                for (int i = 0; i <= height; i+=step){
                    GreenfootImage img2 = new GreenfootImage(width, height);
                    img2.drawImage(img, 0, -i);
                    w.setBackground(img2);
                    linch.setLocation(linch.getX(), height-i+(w.paddingY+1)*i/height);
                    for(Element e: all){
                        e.setLocation(e.getX(), e.getY()-step);
                    }
                    Greenfoot.delay(1);
                }
                w.removeObjects(oldObj);
                w.setBackground(Background.img);

            }
        }
    }

    /**
     * Prüft, an welchen Rand der Linch gekommen ist
     * 
     * @param a Linch
     * @param w Welt
     * @author Florian
     */
    private static int checkMargin(Actor a, Welt w){
        int x = a.getX();
        int y = a.getY();

        if(x <= w.paddingX){             //y >= height-0.5*padding && y <= height+0.5*padding){
            return 1;
        }
        if((w.width - x) <= w.paddingX){
            return 2;
        }
        if(y <= w.paddingY){
            return 3;
        }
        if((w.height - y) <= w.paddingY){
            return 4;
        }
        return 0;
    } 
}
