#include "m_game.h"
#include "actor.h"
#include "room.h"
#include "jui.h"
#include "jinput.h"
#include "jgame.h"
#include "console.h"
#include "editor.h"
#include "jutil.h"
#include "jaudio.h"
#include "config.h"
#include "controller.h"

namespace modules
{
    namespace game
    {
        std::vector<std::string> gifs;
        int treeview_scroll = 0;

        std::vector<std::string> getGifs() { return gifs; }

        vec2_t floating_position = {3,3};

        void init(const bool prologo)
        {
            actor::hero::setPrologo(prologo);
            actor::clear(true);
            ::game::setUpdateTicks(64);
            actor::templates::load();

            if (editor::isDevMode())
            {
                draw::setPaletteColor(100, 0xbb, 0x80, 0x80);
                draw::setPaletteColor(101, 0xff, 0xc0, 0xc0);
                draw::stencil::init();

                FILE* f = fopen("data/gifs.txt", "r");
                int buffer_len=255;
                char buffer[buffer_len];
                while(fgets(buffer, buffer_len, f)) {
                    auto len = strlen(buffer);
                    buffer[len-1]=0;
                    gifs.push_back(std::string(buffer));
                }
                fclose(f);
            } else {
                audio::playMusic("mus_ingame.ogg");
            }

            actor::hero::init();
            room::load(actor::hero::isPrologo()?64:0);
        }

        void print(int x, int y, int num)
        {
            int digits=0;
            bool sign = num < 0;
            num = SDL_abs(num);
            int n = num;
            while (n>0) {n=n/10;digits++;}
            if (sign) digits++;
            x=x+digits*4;
            if (num==0) draw::draw(x+4,y,5,7,0,120);
            while (num>0)
            {
                draw::draw(x,y,5,7,(num%10)*5,120);
                num=num/10;
                x=x-4;
            }
            if (sign) draw::draw(x,y,5,7,50,120);
        }

        const bool btn_small(const int x, const int y, int &var, int min, int max)
        {
            char buffer[100];
            const char *result=ui::spin(SDL_itoa(var, buffer, 10), x, y, 17, 11);
            if (result)
            {
                const int value = SDL_atoi(result);
                var=SDL_max(min, SDL_min(max, value));
                return true;
            }
            return false;
        }

        const bool btn_small(const int x, const int y, int &var, int min, int max, int width)
        {
            char buffer[100];
            const char *result=ui::spin(SDL_itoa(var, buffer, 10), x, y, width, 11);
            if (result)
            {
                const int value = SDL_atoi(result);
                var=SDL_max(min, SDL_min(max, value));
                return true;
            }
            return false;
        }

        const bool btn_check(const int x, const int y, const char* label, int &flags, const uint16_t value, const int width=24)
        {
            int result=0;
            if (flags & value) {
                result=ui::check(label, x, y, width, 11, true);
            } else {
                result=ui::check(label, x, y, width, 11, false);
            }
            if (result)
            {
                if (flags & value) {
                    flags = flags & ~value;
                } else {
                    flags = flags | value;
                }
                return true;
            }
            return false;
        }

        const bool btn_opt(const char* label, const int x, const int y, int &var, std::vector<uint8_t> values, std::vector<std::string> labels, const int w=32)
        {
            //draw::print(label, x, y+3, 15, 0);
            ui::label(label, x, y, w, 11);
            int result = 0;
            std::size_t pos = 0;
            while (pos<values.size())
            {
                if (values[pos]==var) break;
                pos++;
            }
            
            result = ui::combo(labels[pos].c_str(), x+w-1, y, 96-w, 11);
            if (result)
            {
                pos++; if (pos==values.size()) pos=0;
                var = values[pos];
                return true;
            }
            return false;
        }

        bool btn_opt2(const char* label, const int x, const int y, char *var, std::vector<std::string> values)
        {
            //draw::print(label, x, y+3, PAPER, 0);
            ui::label(label, x, y, 48, 11);
            int result = 0;
            std::size_t pos = 0;
            std::string v = var;
            while (pos < values.size() && v != values[pos])
            {
                pos++;
            }
            if (pos==values.size()) pos = 0;

            result = ui::combo(var, x+47, y, 48, 11);
            if (result)
            {
                pos++; if (pos==values.size()) pos=0;
                strcpy(var,values[pos].c_str());
                return true;
            }
            return false;
        }

        const bool btn_txt(const char* label, const int x, const int y, char *var)
        {
            //draw::print(label, x, y+3, PAPER, 0);
            ui::label(label, x, y, 48, 11);
            int result = 0;
            result = ui::textbox(var, x+47, y, 48, 11);
            if (result)
            {
                const int len = strlen(var);
                if (result == SDL_SCANCODE_BACKSPACE) {
                    if (len>0) var[len-1] = 0;
                } else {
                    if (len<15) {
                        var[len] = util::scancode_to_char(result);
                        var[len+1] = 0;
                    }
                }
                return true;
            }
            return false;
        }

        int section = SECTION_ROOM;

        void editor_select_by_keyboard()
        {
            if ( !(input::keyDown(SDL_SCANCODE_LCTRL) || input::keyDown(SDL_SCANCODE_RCTRL)) ) return;

            actor::actor_t *selected = actor::getSelected();

            if ( input::keyPressed(SDL_SCANCODE_UP) )
            {
                if (!selected) {
                    actor::actor_t *first = actor::getFirst();
                    while (first && (first->flags&FLAG_IGNORE)) first=first->next;
                    actor::select(first);
                } else {
                    if (selected->prev) {
                        actor::actor_t *prev = selected->prev;
                        while (prev && (prev->flags&FLAG_IGNORE)) prev=prev->prev;
                        actor::select(prev);
                    } else {
                        actor::actor_t *last = actor::getLast();
                        while (last && (last->flags&FLAG_IGNORE)) last=last->prev;
                        actor::select(last);
                    }
                }
                section=SECTION_ACTOR;
            }

            if ( input::keyPressed(SDL_SCANCODE_DOWN) )
            {
                if (!selected) {
                    actor::actor_t *last = actor::getLast();
                    while (last && (last->flags&FLAG_IGNORE)) last=last->prev;
                    actor::select(last);
                } else {
                    if (selected->next) {
                        actor::actor_t *next = selected->next;
                        while (next && (next->flags&FLAG_IGNORE)) next=next->next;
                        if (next) {
                            actor::select(next);
                        } else {
                            actor::actor_t *first = actor::getFirst();
                            while (first && (first->flags&FLAG_IGNORE)) first=first->next;
                            actor::select(first);
                        }
                    } else {
                        actor::actor_t *first = actor::getFirst();
                        while (first && (first->flags&FLAG_IGNORE)) first=first->next;
                        actor::select(first);
                    }
                }
                section=SECTION_ACTOR;
            }
        }

        void editor_move_selected()
        {
            actor::actor_t *selected = actor::getSelected();
            if (!selected) return;
            const int adv = ( input::keyDown(SDL_SCANCODE_LCTRL) || input::keyDown(SDL_SCANCODE_RCTRL) ) ? 8 : 1;

            vec3_t min = room::getMin();
            vec3_t max = room::getMax();

            if ( input::keyDown(SDL_SCANCODE_LEFT) && (input::keyDown(SDL_SCANCODE_LALT) || selected->pos.x>min.x ))
            {
                selected->pos.x-=adv; actor::setDirty(selected); room::editor::modify();
            }
            
            if ( input::keyDown(SDL_SCANCODE_RIGHT) && (input::keyDown(SDL_SCANCODE_LALT) || (selected->pos.x+selected->size.x)<max.x ))
            {
                selected->pos.x+=adv; actor::setDirty(selected); room::editor::modify();
            }
            
            if ( input::keyDown(SDL_SCANCODE_UP) && (input::keyDown(SDL_SCANCODE_LALT) || selected->pos.y>min.y ))
            {
                selected->pos.y-=adv; actor::setDirty(selected); room::editor::modify();
            }
            
            if ( input::keyDown(SDL_SCANCODE_DOWN) && (input::keyDown(SDL_SCANCODE_LALT) || (selected->pos.y+selected->size.y)<max.y ))
            {
                selected->pos.y+=adv; actor::setDirty(selected); room::editor::modify();
            }
            
            if ( input::keyDown(SDL_SCANCODE_PAGEDOWN) && (input::keyDown(SDL_SCANCODE_LALT) || selected->pos.z>min.z ))
            {
                selected->pos.z-=adv; actor::setDirty(selected); room::editor::modify();
            }
            
            if ( input::keyDown(SDL_SCANCODE_PAGEUP) /*&& selected->pos.z<max.z*/ )
            {
                selected->pos.z+=adv; actor::setDirty(selected); room::editor::modify();
            }
        }

        void setSection(int value)
        {
            section = value;
        }

        const int getSection()
        {
            return section;
        }

        char missatge[255] = "";

        void mostra_missatge()
        {
            if ( (controller::pressed(KEY_MENU)) || (controller::pressed(KEY_PICK)) || (controller::pressed(KEY_JUMP)) )
            {
                missatge[0] = 0;
                audio::resumeMusic();
                return;
            }
            draw::color(BLACK);
            draw::fillrect(56, 68, 208, 48);
            draw::color(WHITE);
            draw::rect(56, 68, 208, 48);
            char text[2][25];
            int i=0, j=0, k=0;
            while (missatge[i]!=0)
            {
                if (missatge[i]=='-') { text[k][j]=0; i++; j=0; k++; }
                text[k][j] = missatge[i];
                i++; j++;
            }
            text[k][j]=0;
            draw::print2(text[0], 8, 10, WHITE, FONT_ZOOM_NONE);
            draw::print2(text[1], 8, 12, WHITE, FONT_ZOOM_NONE);

            draw::render();
        }

        int loop()
        {
            if (missatge[0] != 0) { mostra_missatge(); return GAME_NONE; }

            int return_value = GAME_NONE;

            if (actor::hero::isDead()) return GAME_DEAD;

            if (controller::pressed(KEY_MENU))
            {
                if (console::isEnabled()) {
                    console::toggle();
                } else {
                    if (room::editor::isModified()) room::editor::save();
                    actor::pauseWalkSound();

                    return GAME_MENU;
                }
            }

            // WHILE EDITING...
            if (editor::isEditing())
            {
                if (input::keyPressed(SDL_SCANCODE_TAB)) return GAME_EDITOR_MAP;
                if (input::keyPressed(SDL_SCANCODE_GRAVE)) return GAME_EDITOR_TEMPLATES;

                editor_move_selected();
                actor::updateEditor(actor::getFirst());
            }
            else
            {
                if (input::keyPressed(SDL_SCANCODE_TAB) || input::keyPressed(SDL_SCANCODE_GRAVE) ) console::toggle();

                if (!console::update())
                {
                    actor::update(actor::getFirst());
                    actor::hero::useBoostGod();
                    if ( (actor::hero::getParts()==0x3f) && (room::getCurrent()==45) ) return GAME_END;
                    if ( (actor::hero::getNumPrologoObjectsDone()==4) && (room::getCurrent()==64) ) return GAME_PROLOGO_END;
                }
            }

            actor::reorder();
            //if (editor::isEditing()) editor_select_by_keyboard();

            draw::resetViewport();
            draw::cls(2);

            if (editor::isDevMode()) draw::setViewport(100,0,320,240);

            room::draw();

            actor::actor_t *selected = actor::getSelected();
            const bool inside_room_zone = (draw::getLocalX(input::mouseX())>=0 && draw::getLocalY(input::mouseY())>=0 && draw::getLocalX(input::mouseX())<320 && draw::getLocalY(input::mouseY())<240);

            if (editor::isDevMode() && selected && inside_room_zone && input::keyPressed(SDL_SCANCODE_M)) actor::setFloatingEditing(true);

            if (editor::isDevMode() && actor::getFloatingEditing() && selected) {
                draw::swapcol(1, GREEN+LIGHT);
                draw::setSource(draw::getSurface("test.gif"));
                const float px = draw::getLocalX(input::mouseX())-148-16;
                const float py = draw::getLocalY(input::mouseY())-75;
                const int x = int(py/16.0f + px/32.0f);
                const int y = int(py/16.0f - px/32.0f);

                //draw::print2(x, -3, 1, 6, PURPLE, FONT_ZOOM_NONE);
                //draw::print2(y, -3, 1, 7, PURPLE, FONT_ZOOM_NONE);

                if (x>=room::getTMin().x && y>=room::getTMin().y && x<=room::getTMax().x && y<=room::getTMax().y)
                {
                    floating_position = {x, y};
                    selected->pos.x = floating_position.x*8;
                    selected->pos.y = floating_position.y*8;
                }
                draw::draw(148+floating_position.x*16-floating_position.y*16,75+floating_position.x*8+floating_position.y*8,32,16,160,0);
                if (input::mouseClk(1)) { actor::setFloatingEditing(false); room::editor::modify(); }
            }

            draw::stencil::enable();
            draw::stencil::clear(255);
            actor::draw(actor::getFirst());
            draw::stencil::disable();
            room::draw2();
            draw::swapcol(1, WHITE+LIGHT);
            actor::draw(actor::getPicked(), false);
            
            // Si estem en el editor, fent click en els actors els seleccionem
            if (editor::isDevMode() && input::mouseBtn(1) && !actor::getFloatingEditing())
            {
                const uint8_t val = draw::stencil::query(input::mouseX(), input::mouseY());
                if (val != 255)
                {
                    actor::select(actor::findByTag(val));
                    section = SECTION_ACTOR;
                }
                else if (input::mouseX()>=0 && input::mouseX()<320 && input::mouseY()>=0 && input::mouseY()<240)
                {
                    section = SECTION_ROOM;
                }
            }

            // Si estem jugant, o estem en el editor pero NO en mode edició, pinta els marcadors
            if (!editor::isEditing())
            {
                const int col1 = room::getColor(1);
                const int col2 = room::getColor(2);
                const int col3 = room::getColor(3);

                //draw::print2("hi", 4, 24, col3, FONT_ZOOM_NONE);
                draw::print2("no", 4, 25, col3, FONT_ZOOM_NONE);
                draw::print2(actor::hero::getLives(), 2, 4, 26, col1, FONT_ZOOM_VERTICAL);

                if (!actor::hero::isPrologo())
                {
                    draw::print2("a", 9, 26, col1, FONT_ZOOM_NONE);
                    draw::print2("b", 12, 26, col2, FONT_ZOOM_NONE);
                    draw::print2("c", 15, 26, col3, FONT_ZOOM_NONE);
                
                    draw::print2(actor::hero::getBoostJump(), 2, 8, 27, col3, FONT_ZOOM_NONE);
                    draw::print2(actor::hero::getBoostGod()/2, 2, 11, 27, col1, FONT_ZOOM_NONE);
                    draw::print2(actor::hero::getBoostRun()/2, 2, 14, 27, col2, FONT_ZOOM_NONE);

                    draw::stencil::enable();
                    draw::stencil::clear(255);

                    draw::setSource(draw::getSurface("objectes.gif"));
                    draw::stencil::set(SKILL_SHOES);
                    draw::swapcol(1, actor::hero::getSkills()&SKILL_SHOES ? col1 : col3);
                    draw::draw(276,166, 28, 22, 162, 0);
                    draw::stencil::set(SKILL_PANTS);
                    draw::swapcol(1, actor::hero::getSkills()&SKILL_PANTS ? col1 : col3);
                    draw::draw(250,183, 18, 23, 167, 22);
                    draw::stencil::set(SKILL_GLOVES);
                    draw::swapcol(1, actor::hero::getSkills()&SKILL_GLOVES ? col1 : col3);
                    draw::draw(222,200, 21, 22, 165, 45);
                    draw::stencil::set(SKILL_BAG);
                    draw::swapcol(1, actor::hero::getSkills()&SKILL_BAG ? col1 : col3);
                    draw::draw(279,200, 20, 25, 145, 41);

                    draw::stencil::disable();

                    // Si estem en el editor, fent click en els skills del marcador els obtenim
                    if (editor::isDevMode() && input::mouseClk(1))
                    {
                        const uint8_t val = draw::stencil::query(input::mouseX(), input::mouseY());
                        if (val != 255)
                        {
                            if (actor::hero::getSkills() & val)
                                actor::hero::dropSkill(val);
                            else
                                actor::hero::giveSkill(val);
                            
                            room::cycleColor(1);
                        }
                    }
                } else if (actor::hero::isCarryingPrologoObject())
                {
                    draw::setSource(draw::getSurface("objectes.gif"));
                    if (actor::hero::getPrologoObjectState(PROLOGO_SHOES)==PROLOGO_OBJECT_PICKED)
                    {
                        draw::draw(276,166, 28, 22, 162, 0);
                    } else if (actor::hero::getPrologoObjectState(PROLOGO_PANTS)==PROLOGO_OBJECT_PICKED)
                    {
                        draw::draw(276,166, 18, 23, 167, 22);
                    } else if (actor::hero::getPrologoObjectState(PROLOGO_GLOVES)==PROLOGO_OBJECT_PICKED)
                    {
                        draw::draw(276,166, 21, 22, 165, 45);
                    } else if (actor::hero::getPrologoObjectState(PROLOGO_BAG)==PROLOGO_OBJECT_PICKED)
                    {
                        draw::draw(276,166, 20, 25, 145, 41);
                    }
                }
            }


        /*
            print(0,0,input::mouseX());
            print(0,20,input::mouseY());
            print(0,30,input::mouseBtn(1)?1:0);
            print(0,40,input::mouseBtn(2)?1:0);
            print(0,50,input::mouseBtn(3)?1:0);
        */

            // Si no estem en el editor, pintem la consola (si es el cas), renderitzem i eixim
            if (!editor::isDevMode())
            {
                console::draw();
                draw::render();
                return GAME_NONE;
            }

            // Si estem en el editor, pintem els numerets de les eixides
            draw::print2(room::getExit(XN), -2, 1, 1, TEAL, FONT_ZOOM_NONE);
            draw::print2(room::getExit(YN), -2, 38, 1, TEAL, FONT_ZOOM_NONE);
            draw::print2(room::getExit(XP), -2, 38, 28, TEAL, FONT_ZOOM_NONE);
            draw::print2(room::getExit(YP), -2, 1, 28, TEAL, FONT_ZOOM_NONE);
            draw::print2(room::getExit(ZP), -2, 19, 1, TEAL, FONT_ZOOM_NONE);
            draw::print2(room::getExit(ZN), -2, 19, 28, TEAL, FONT_ZOOM_NONE);

            // ...i l'habitació actual
            draw::print2(room::getCurrent(), -2, 4, 3, WHITE, FONT_ZOOM_BOTH);

            // ...i la marca de habitació completada
            draw::color(WHITE);
            draw::rect(250, 24, 20, 20);
            if (room::editor::refEditorDone())
            {
                draw::color(RED);
                draw::fillrect(252, 26, 16, 16);
            }

            // ...i fent click en els numerets de les eixides anem a l'habitació corresponent
            // Es més. Si no hi ha habitació enllaçada en una eixida i li fem ctrl+click, se crea una nova habitació per eixa eixida
            if (input::mouseClk(1)) {
                const int mx = draw::getLocalX(input::mouseX());
                const int my = draw::getLocalY(input::mouseY());
                if (mx>=0 && my>=0 && mx<320 && my<240) {
                    if (mx<32  && my<24) {
                        int room = room::editor::refExit(XN);
                        if (room>=0 || input::keyDown(SDL_SCANCODE_LCTRL)) room::load(room, XP);
                    }
                    if (mx>288 && my<24) {
                        int room = room::editor::refExit(YN);
                        if (room>=0 || input::keyDown(SDL_SCANCODE_LCTRL)) room::load(room, YP);
                    }
                    if (mx>288 && my>216) {
                        int room = room::editor::refExit(XP);
                        if (room>=0 || input::keyDown(SDL_SCANCODE_LCTRL)) room::load(room, XN);
                    }
                    if (mx<32  && my>216) {
                        int room = room::editor::refExit(YP);
                        if (room>=0 || input::keyDown(SDL_SCANCODE_LCTRL))
                            room::load(room, YN);
                    }
                    if (mx>144 && mx<176 && my<24) {
                        int room = room::editor::refExit(ZP);
                        if (room>=0 || input::keyDown(SDL_SCANCODE_LCTRL)) room::load(room, ZN);
                    }
                    if (mx>144 && mx<176 && my>216) {
                        int room = room::editor::refExit(ZN);
                        if (room>=0 || input::keyDown(SDL_SCANCODE_LCTRL)) room::load(room, ZP);
                    }

                    if (mx>=250 && mx<270 && my>=24 && my<44) {
                        room::editor::refEditorDone() = room::editor::refEditorDone() ? 0 : 1;
                        room::editor::modify(); room::update();
                    }
                    
                }
            }

            // Pintem tota la UI del editor
            // ================================================================================
            ui::start();

            actor::actor_t *act = nullptr;

            draw::setViewport(0,0,100,240);
            draw::color(WHITE);
            draw::fillrect(0, 0, 100, 240);

/*
            int result = ui::combo(actor::templates::get(editor::getCurrentTemplate())->name, 2, 2, 76, 11);
            if (result)
            {
                int new_current_template = editor::getCurrentTemplate() + (result-2);
                if (new_current_template >= actor::templates::size()) new_current_template = 0;
                if (new_current_template < 0) new_current_template = actor::templates::size()-1;
                editor::setCurrentTemplate(new_current_template);
            }
            if (ui::button("NEW", 78, 2, 20, 11))
            {
                actor::actor_t *new_act = actor::duplicate(actor::templates::get(editor::getCurrentTemplate()));
                actor::setUniqueName(new_act);
                actor::setDirty(new_act, true);
                actor::select(new_act);
                room::editor::modify();
            }
*/
            draw::color(LIGHT+WHITE);
            draw::fillrect(2, 15, 96, 223);
            draw::color(PAPER);
            draw::rect(2, 15, 96, 223);

            draw::setViewport(0, 15, 100, 222);

            int mx = draw::getLocalX(input::mouseX());
            int my = draw::getLocalY(input::mouseY());
            //const bool btnDown = input::mouseBtn(1) || input::mouseBtn(3);
            const bool btnClk = input::mouseClk(1) || input::mouseClk(3);
            
            if (mx>=0 && mx <=100 && my>=0 && my<=221)
            {
                treeview_scroll -= input::mouseWheel();
                if (treeview_scroll<0) treeview_scroll=0;
            }

            switch (section)
            {
                case SECTION_GENERAL: treeview_scroll = 0; break;
                case SECTION_ROOM: if (treeview_scroll > room::editor::getCurrentRoom()+1) treeview_scroll = room::editor::getCurrentRoom()+1;
            }

            int line = -treeview_scroll;
/*
            if (section==SECTION_GENERAL)
            {
                draw::color(LIGHT+BLUE);
                draw::fillrect(4, 2+line*9, 92, 9);
            }
            if ((mx>=2) && (mx<98) && (my>=2+line*9) && (my<2+9+line*9) && btnDown) {
                section = SECTION_GENERAL;
            }
            //draw::print("-THE POOL", 6, 4+line*9, LIGHT+WHITE, BLACK);
            //line++;
*/
            if (section==SECTION_ROOM)
            {
                for (int i=0;i<MAX_ROOMS;++i)
                {
                    if (room::editor::roomExists(i)) 
                    {
                        if (i == room::editor::getCurrentRoom())
                        {
                            draw::color(LIGHT+BLUE);
                            draw::fillrect(4, 2+line*9, 92, 9);
                        }
                        if ((mx>=2) && (mx<98) && (my>=2+line*9) && (my<2+9+line*9) && btnClk) {
                            if (i == room::editor::getCurrentRoom()) {
                                section = SECTION_ACTOR;
                            } else {
                                room::load(i);
                            }
                        }
                        char num[] = "+ROOM 00";
                        num[6] = int(i/10)+48;
                        num[7] = (i%10)+48;
                        draw::print(num, 6, 4+line*9, LIGHT+WHITE, BLACK); line++;
                    }
                }
            } else if (section==SECTION_ACTOR)
            {
                if ((mx>=2) && (mx<98) && (my>=2+line*9) && (my<2+9+line*9) && btnClk) {
                    section = SECTION_ROOM;
                }

                const int i = room::editor::getCurrentRoom();
                char num[] = "-ROOM 00";
                num[6] = int(i/10)+48;
                num[7] = (i%10)+48;
                draw::print(num, 6, 4+line*9, LIGHT+WHITE, BLACK); line++;
                
                act = actor::alphaOrder(actor::getFirst());
                while (act)
                {
                    if ((act->flags&FLAG_NOEDITOR)!=FLAG_NOEDITOR && (act->flags&FLAG_HERO)!=FLAG_HERO) {
                        if (act==actor::getSelected()) {
                            draw::color(LIGHT+BLUE);
                            draw::fillrect(4, 2+line*9, 92, 9);
                        }
                        if ((mx>=2) && (mx<98) && (my>=2+line*9) && (my<2+9+line*9) && btnClk) {
                            actor::select(act);
                            section = SECTION_ACTOR;
                        }
                        draw::print(act->name, 14, 4+line*9, LIGHT+WHITE, BLACK);
                        line++;
                    }
                    act = act->next_alpha;
                }
            }

            if ((line+treeview_scroll)>24)
            {
                const float total_size = float(line+treeview_scroll);
                int ascensor_length = 222.0f/(total_size/24.0f);
                int ascensor_pos = 222.0f/(total_size/treeview_scroll);
                draw::color(WHITE);
                draw::fillrect(95, ascensor_pos, 2, ascensor_length);
            }







            draw::setViewport(420, 0, 100, 240);
            draw::color(WHITE);
            draw::fillrect(0, 0, 100, 240);

            if (ui::button("EDITING", 2, 2, 96, 11, editor::isEditing()))
            {
                room::load(room::editor::getCurrentRoom());
                if (!editor::isEditing())
                {
                    actor::actor_t *hero = actor::find("HERO");
                    hero->pos.x = hero->pos.y = 32; hero->pos.z = 0;
                }
                editor::setEditing(!editor::isEditing());
            }

            draw::setViewport(420, 15, 100, 225);


            bool changed = false;


            switch (section)
            {
                case SECTION_GENERAL:
                    break;

                case SECTION_ROOM:
                    draw::color(LIGHT+WHITE);
                    draw::fillrect(2, 0, 96, 223);

                    line = 0;
                    //changed |= btn("ROOM WIDTH:", 10, 40, room::editor::refWidth(), 0, 3);
                    //changed |= btn("ROOM HEIGHT:", 10, 55, room::editor::refHeight(), 0, 3);
                    ui::label("ROOM DIMENSIONS", 2, line, 96, 11, GRAY); line+=10;

                    ui::label("WIDTH", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refWidth(), 0, 3, 50);
                    line += 10;
                    ui::label("HEIGHT", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refHeight(), 0, 3, 50);
                    line += 10;

                    ui::label("DOOR HEIGHTS", 2, line, 96, 11, GRAY); line+=10;

                    ui::label("XN", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refDoor(XN), -1, 5, 50);
                    line += 10;
                    ui::label("YP", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refDoor(YP), -1, 5, 50);
                    line += 10;
                    ui::label("XP", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refDoor(XP), -1, 5, 50);
                    line += 10;
                    ui::label("YN", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refDoor(YN), -1, 5, 50);
                    line += 10;

                    ui::label("TEXTURES", 2, line, 96, 11, GRAY); line+=10;

                    //changed |= btn_opt("COLOR", 2, line, room::editor::refColor(), {0, 1, 2, 3, 4}, {"PURPLE", "GREEN", "CYAN", "YELLOW", "WHITE"}, 47);        //ui::label("COLOR", 2, line, 64, 11);
                    {
                        const char *colors[] = {"PURPLE", "GREEN", "CYAN", "YELLOW", "WHITE"};
                        ui::label("COLOR", 2, line, 48, 11);
                        const int color = room::editor::refColor();
                        if (ui::combo(colors[color], 48, line, 49, 11)) {
                        //if (ui::button(colors[room::editor::refColor()], 48, line+1, 49, 9)) {
                            //ui::button(colors[room::editor::refColor()], 48, line+1, 49, 9, true);
                            return_value = GAME_EDITOR_COLORS;
                        }
                        draw::color(LIGHT+color+7); draw::fillrect(77,2+line,7,7);draw::color(PAPER); draw::rect(77,2+line,7,7);
                    }

                    line += 10;
                    ui::label("FLOOR", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refFloorTex(), 0, room::getFloorCount()-1, 50);
                    line += 10;
                    ui::label("WALL", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refWallTex(), 0, room::getWallsCount()-1, 50);
                    line += 10;
                    ui::label("DOOR", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refDoorTex(), 0, room::getDoorCount()-1, 50);
                    line += 10;
                    ui::label("UNDER DOOR", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refWallDoorTex(), 0, room::getWallsCount()-1, 50);
                    line += 10;

                    ui::label("EXITS", 2, line, 96, 11, GRAY); line+=10;

                    ui::label("XN", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refExit(XN), -1, MAX_ROOMS, 36);
                    if (ui::button("GO", 84, line, 13, 11)) room::load(room::editor::refExit(XN), XP);
                    line += 10;
                    ui::label("YP", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refExit(YP), -1, MAX_ROOMS, 36);
                    if (ui::button("GO", 84, line, 13, 11)) room::load(room::editor::refExit(YP), YN);
                    line += 10;
                    ui::label("XP", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refExit(XP), -1, MAX_ROOMS, 36);
                    if (ui::button("GO", 84, line, 13, 11)) room::load(room::editor::refExit(XP), XN);
                    line += 10;
                    ui::label("YN", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refExit(YN), -1, MAX_ROOMS, 36);
                    if (ui::button("GO", 84, line, 13, 11)) room::load(room::editor::refExit(YN), YP);
                    line += 10;
                    ui::label("ZP", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refExit(ZP), -1, MAX_ROOMS, 36);
                    if (ui::button("GO", 84, line, 13, 11)) room::load(room::editor::refExit(ZP), ZN);
                    line += 10;
                    ui::label("ZN", 2, line, 48, 11);
                    changed |= btn_small(48, line, room::editor::refExit(ZN), -1, MAX_ROOMS, 36);
                    if (ui::button("GO", 84, line, 13, 11)) room::load(room::editor::refExit(ZN), ZP);
                    line += 10;

                    /*changed |= btn("COLOR:", 10, 140, room::editor::refColor(), 5, 11);
                    changed |= btn("FLOOR:", 10, 155, room::editor::refFloorTex(), 0, 5);
                    changed |= btn("WALLS:", 10, 170, room::editor::refWallTex(), 0, 5);
                    changed |= btn("DOORS:", 10, 185, room::editor::refDoorTex(), 0, 4);
                    changed |= btn("WDOORS:", 10, 200, room::editor::refWallDoorTex(), 0, 5);*/

                    if (changed) { room::editor::modify(); room::update(); }

                    draw::color(PAPER);
                    draw::rect(2, 0, 96, 223);

                    break;

                case SECTION_ACTOR:
                    draw::color(LIGHT+WHITE);
                    draw::fillrect(2, 0, 96, 153);

                    changed = false;
                    act = actor::getSelected();
                    if (act)
                    {
                        line = 0;
                        //draw::setViewport(420, 90, 100, 150);

                        changed |= btn_txt("NAME", 2, line, act->name); line+=10;

                        ui::label("LOCATION", 2, line, 96, 11, GRAY); line+=10;

                        ui::label("POS", 2, line, 48, 11);
                        changed |= btn_small(49, line, act->pos.x, 0, 512);
                        changed |= btn_small(65, line, act->pos.y, 0, 512);
                        changed |= btn_small(81, line, act->pos.z, 0, 512);
                        line+=10;

                        ui::label("SIZE", 2, line, 48, 11);
                        changed |= btn_small(49, line, act->size.x, 0, 512);
                        changed |= btn_small(65, line, act->size.y, 0, 512);
                        changed |= btn_small(81, line, act->size.z, 0, 512);
                        line+=10;

                        ui::label("BITMAP", 2, line, 96, 11, GRAY); line+=10;

                        {
                            ui::label("FILE", 2, line, 49, 11);
                            if (ui::combo(act->bmp, 49, line, 48, 11)) {
                            //if (ui::button(colors[room::editor::refColor()], 48, line+1, 49, 9)) {
                                //ui::button(colors[room::editor::refColor()], 48, line+1, 49, 9, true);
                                return_value = GAME_EDITOR_BITMAP_FILE;
                            }
                        }

/*
                        if (btn_opt2("FILE", 2, line, act->bmp, gifs)) {
                            //draw::freeSurface(act->surface);
                            act->surface = draw::getSurface(act->bmp);
                            changed = true;
                        }
*/
                        mx = draw::getLocalX(input::mouseX());
                        my = draw::getLocalY(input::mouseY());

                        line+=10;
                        ui::label("POS", 2, line, 48, 11);
                        if (input::mouseClk(1) && mx>=2 && mx <=48 && my>=line && my<=line+10) return_value = GAME_EDITOR_BITMAP_POS;
                        changed |= btn_small(49, line, act->bmp_rect.x, 0, 512, 25);
                        changed |= btn_small(73, line, act->bmp_rect.y, 0, 512, 25);
                        line+=10;
                        ui::label("SIZE", 2, line, 48, 11);
                        if (input::mouseClk(1) && mx>=2 && mx <=48 && my>=line && my<=line+10) return_value = GAME_EDITOR_BITMAP_SIZE;
                        changed |= btn_small(49, line, act->bmp_rect.w, 0, 512, 25);
                        changed |= btn_small(73, line, act->bmp_rect.h, 0, 512, 25);
                        line+=10;
                        ui::label("OFFSET", 2, line, 48, 11);
                        changed |= btn_small(49, line, act->bmp_offset.x, -32, 64, 25);
                        changed |= btn_small(73, line, act->bmp_offset.y, -32, 64, 25);
                        line+=10;

                        ui::label("FLAGS", 2, line, 96, 11, GRAY);
                        changed |= btn_check(26, line, "DISA", act->flags, FLAG_DISAPPEAR);
                        changed |= btn_check(50, line, "INER", act->flags, FLAG_INERTIA);
                        changed |= btn_check(74, line, "SPEC", act->flags, FLAG_SPECIAL);
                        line+=10;

                        changed |= btn_check(2, line, "PICK", act->flags, FLAG_PICKABLE);
                        changed |= btn_check(26, line, "PUSH", act->flags, FLAG_PUSHABLE);
                        changed |= btn_check(50, line, "REAC", act->flags, FLAG_REACTIVE);
                        changed |= btn_check(74, line, "MOVI", act->flags, FLAG_MOVING);
                        line+=10;
                        changed |= btn_check(2, line, "ANIM", act->flags, FLAG_ANIMATED);
                        changed |= btn_check(26, line, "ORIE", act->flags, FLAG_ORIENTABLE);
                        changed |= btn_check(50, line, "DEAD", act->flags, FLAG_DEADLY);
                        changed |= btn_check(74, line, "GRAV", act->flags, FLAG_GRAVITY);
                        line+=11;

                        ui::label("PROPERTIES", 2, line, 96, 11, GRAY); line+=10;

                        if (btn_opt("ORIENT", 2, line, act->orient, {PUSH_NONE, PUSH_XP, PUSH_XN, PUSH_YP, PUSH_YN, PUSH_ZP, PUSH_ZN}, {"NONE", "XP", "XN", "YP", "YN", "ZP", "ZN"}, 48))
                        {
                            act->mov_push = act->orient;
                            changed = true;
                        }
                        line+=10;

                        changed |= btn_opt("MOVEMNT", 2, line, act->movement, {MOV_NONE, MOV_X, MOV_Y, MOV_Z, MOV_CW, MOV_CCW, MOV_RAND, MOV_RANDV, MOV_HUNT, MOV_RANDJ}, {"NONE", "X", "Y", "Z", "CW", "CCW", "RAND", "RANDV", "HUNT", "RANDJ"}, 48);
                        line+=10;
                        changed |= btn_opt("ANIMCYC", 2, line, act->anim_cycle, {0, 1, 2, 3}, {"0 1 0 2", "0 1 2 3", "0 1 2", "0 1 0 1"}, 48);
                        line+=10;

                        //draw::print("ANIM SPEED:", 2, 156, 15, 0);
                        ui::label("ANMSPED", 2, line, 49, 11);
                        changed |= btn_small(49, line, act->anim_wait, 0, 20, 49);
                        line+=10;

                        ui::label("MASKS", 2, line, 96, 11, GRAY); line+=10;

                        ui::label("RMASK", 2, line, 24, 11);
                        changed |= btn_check(24+2, line, "XP", act->react_mask, PUSH_XP, 12);
                        changed |= btn_check(24+14, line, "XN", act->react_mask, PUSH_XN, 12);
                        changed |= btn_check(24+26, line, "YP", act->react_mask, PUSH_YP, 12);
                        changed |= btn_check(24+38, line, "YN", act->react_mask, PUSH_YN, 12);
                        changed |= btn_check(24+50, line, "ZP", act->react_mask, PUSH_ZP, 12);
                        changed |= btn_check(24+62, line, "ZN", act->react_mask, PUSH_ZN, 12);
                        line+=11;

                        ui::label("RPUSH", 2, line, 24, 11);
                        changed |= btn_check(24+2, line, "XP", act->react_push, PUSH_XP, 12);
                        changed |= btn_check(24+14, line, "XN", act->react_push, PUSH_XN, 12);
                        changed |= btn_check(24+26, line, "YP", act->react_push, PUSH_YP, 12);
                        changed |= btn_check(24+38, line, "YN", act->react_push, PUSH_YN, 12);
                        changed |= btn_check(24+50, line, "ZP", act->react_push, PUSH_ZP, 12);
                        changed |= btn_check(24+62, line, "ZN", act->react_push, PUSH_ZN, 12);
                        line+=12;

                        draw::color(PAPER);
                        draw::rect(2, 0, 96, 204);
                        
                        if (ui::button("DUPLICATE", 2, line, 48, 11) || ( input::keyPressed(SDL_SCANCODE_D) && inside_room_zone))
                        {
                            actor::actor_t *new_act = actor::duplicate(act);
                            actor::setUniqueName(new_act);
                            //new_act->pos.x++; new_act->pos.y++;
                            actor::setDirty(new_act, true);
                            actor::select(new_act);
                            actor::setFloatingEditing(true);
                            changed = true;
                        }
                        if (ui::button("DELETE", 48, line, 48, 11) || ( input::keyPressed(SDL_SCANCODE_DELETE) && inside_room_zone))
                        {
                            actor::remove(act);
                            act = nullptr;
                            changed = true;
                        }
                        line+=10;

                        if (changed) { room::editor::modify(); }

                        if (ui::button("ADD TO TEMPLATES", 2, line, 96, 11))
                        {
                            if (act) actor::templates::add(act);
                        }
                        //changed |= btn_opt("ANIMCYC", 2, 106, act->anim_cycle, {0, 1}, {"0 1 0 2", "0 1 2 3"});

                    }
                    break;
            };

            draw::render();
            return return_value;

        }

        void setMissatge(const char *text)
        {
            actor::pauseWalkSound();
            audio::pauseMusic();
            strcpy(missatge, text);
        }

    }
}
