#include "selection.h"

Selection::Selection(void)
{   
    first.X=-1; first.Z=-1;
    last.X=-1;  last.Z=-1;
}

Selection::Selection(int x, int z)
{   
    first.X=x;  first.Z=z;
    last.X=x;   last.Z=z;
}

Selection::~Selection(void) { }

void Selection::set(int returnfirstPick ,int returnSecondPick)
{
int coordX1=returnfirstPick%100;
int coordZ1=returnfirstPick/100;
int coordX2=returnSecondPick%100;
int coordZ2=returnSecondPick/100;

if (coordX1<coordX2){first.X=coordX1; last.X= coordX2;}
else                {first.X=coordX2;  last.X= coordX1;}
if (coordZ1<coordZ2){first.Z=coordZ1;  last.Z= coordZ2;}
else                { first.Z=coordZ2; last.Z= coordZ1;}

applied=false;

}

void Selection::flat(MadMap *map, double h)
{   for (int i=first.Z ;i<=last.Z;i++)
                for (int j=first.X;j<=last.X;j++){
                                map->setY(j+0.1,i+0.1,h);
                                map->setY(j+0.9,i+0.1,h);
                                map->setY(j+0.1,i+0.9,h);
                                map->setY(j+0.9,i+0.9,h);}
                
}

void Selection::up(MadMap *map, double k){
for (int i=first.Z ;i<=last.Z;i++)
                for (int j=first.X;j<=last.X;j++)
                    map->upTile(j,i,k);
}

void Selection::zero(MadMap *map,double k)
{
for (int i=first.Z ;i<=last.Z;i++)
                for (int j=first.X;j<=last.X;j++)
                    map->zeroTile(j,i,k);
}

void Selection::level(MadMap *map, double k)
{
    double h;
    for (int i=first.Z ;i<=last.Z;i++)
                for (int j=first.X;j<=last.X;j++){
                                    
                                h=map->getY(j+0.5,i+0.5)+k;
                            
                                map->setY(j+0.1,i+0.1,h);
                                map->setY(j+0.9,i+0.1,h);
                                map->setY(j+0.1,i+0.9,h);
                                map->setY(j+0.9,i+0.9,h); }
}

void Selection::slide(MadMap *map, double k)
{
    double h;
    int i,j;
    if ((last.Z==first.Z)& (first.X==last.X)){
                            h=map->getY(first.X+0.5,last.Z+0.5);
                            h=h+k;
                            map->setY(first.X+0.5,last.Z+0.5,h);
                        }
                        else
                         if ((last.Z==first.Z)){i =last.Z;
                            for (int j=first.X+1;j<=last.X;j++)
                            {
                                h=map->getY(j,i);
                                h=h+k;
                                
                                map->setY(j-0.1,i+0.1,h);
                                map->setY(j-0.1,i+0.9,h);
                                map->setY(j+0.1,i+0.1,h);
                                map->setY(j+0.1,i+0.9,h);

                            
                        }
                            }
                         else
    
                         if ((last.X==first.X)){int j =last.X;
                            for (int i=first.Z+1;i<=last.Z;i++)
                            {
                                h=map->getY(j,i);
                                h=h+k;
                                
                                map->setY(j+0.9,i-0.1,h);
                                map->setY(j+0.9,i+0.1,h);
                                map->setY(j+0.1,i-0.1,h);
                                map->setY(j+0.1,i+0.1,h);

                            
                        }
                            }
                         else 
                    for (i=first.Z+1 ;i<=last.Z;i++)
                        for ( j=first.X+1;j<=last.X;j++)
                        {
                        h=map->getY(j,i);
                        h=h+k;
                        map->setY(j+0.1,i+0.1,h);
                        map->setY(j-0.1,i-0.1,h);
                        map->setY(j+0.1,i-0.1,h);
                        map->setY(j-0.1,i+0.1,h);
                                
                        
                        
                        }   
                        
                                
}
    



void Selection::incline(MadMap *map,double k)
{
    double h,i,j,o;
    if (map->getY(first.X,first.Z)==map->getY(last.X,last.Z)){
    for (int i=first.Z ;i<=last.Z;i++)
                for (int j=first.X;j<=last.X;j++)
                {   
                    
                    h=map->getY(j,i);
                
                    o=h;
                    if ((last.X-first.X)>(last.Z-first.Z))
                    
                            h=h+k*(j-first.X);
                    
                            else 
                                h=h+k*(i-first.Z);
                    if (h>o) {
                    map->setY(j+0.1,i+0.9,h);
                    map->setY(j+0.9,i+0.1,h);
                    map->setY(j+0.9,i+0.9,h);
                    map->setY(j+0.1,i+0.1,h);}
            
            }
                for (int i=last.Z ;i>=first.Z;i--)
                for (int j=last.X;j>=first.X;j--)
                {
                            h=map->getY(j,i);
o=h;
                if ((last.X-first.X)>(last.Z-first.Z)) h=h-k*(-j+last.X);
                                else h=h-k*(-i+last.Z);
                if (h>o) {
                    map->setY(j+0.1,i+0.9,h);
                    map->setY(j+0.9,i+0.1,h);
                    map->setY(j+0.9,i+0.9,h);
                                map->setY(j+0.1,i+0.1,h);
                    
                }   } }

else
if (map->getY(first.X,first.Z)<map->getY(last.X,last.Z))
        for (int i=first.Z ;i<=last.Z;i++)
                for (int j=first.X;j<=last.X;j++)
                {   
                    
                        h=map->getY(j,i);
                    if ((last.X-first.X)>(last.Z-first.Z))
                    
                            h=h+k*(j-first.X);
                    
                            else 
                                h=h+k*(i-first.Z);
                    
                    map->setY(j+0.1,i+0.9,h);
                    map->setY(j+0.9,i+0.1,h);
                    map->setY(j+0.9,i+0.9,h);
                    map->setY(j+0.1,i+0.1,h);
            
                }



else
        for (int i=last.Z ;i>=first.Z;i--)
                for (int j=last.X;j>=first.X;j--)
                {
                            h=map->getY(j,i);

                if ((last.X-first.X)>(last.Z-first.Z)) h=h-k*(-j+last.X);
                                else h=h-k*(-i+last.Z);
    map->setY(j+0.1,i+0.9,h);
                    map->setY(j+0.9,i+0.1,h);
                    map->setY(j+0.9,i+0.9,h);
                                map->setY(j+0.1,i+0.1,h);
                    
                }   

 i =last.Z;

                            for ( j=first.X+1;j<=last.X;j++)
                            {
                                h=map->getY(j,i);
                            
                                
                                map->setY(j-0.1,i+0.1,h);
                                map->setY(j-0.1,i+0.9,h);
                                map->setY(j+0.1,i+0.1,h);
                                map->setY(j+0.1,i+0.9,h);
                            
                        }
 i =first.Z;

                            for ( j=first.X+1;j<=last.X;j++)
                            {
                                h=map->getY(j,i);
                            
                                
                                map->setY(j-0.1,i+0.1,h);
                                map->setY(j-0.1,i+0.9,h);
                                map->setY(j+0.1,i+0.1,h);
                                map->setY(j+0.1,i+0.9,h);
                            
                        }

                        //  }
                    j =last.X;
                
                            for ( i=first.Z+1;i<=last.Z;i++)
                            {
                                h=map->getY(j,i);
                                
                                
                                map->setY(j+0.9,i-0.1,h);
                                map->setY(j+0.9,i+0.1,h);
                                map->setY(j+0.1,i-0.1,h);
                                map->setY(j+0.1,i+0.1,h);
                                
                            
                        }
    j =first.X;
                
                            for ( i=first.Z+1;i<=last.Z;i++)
                            {
                                h=map->getY(j,i);
                                
                                
                                map->setY(j+0.9,i-0.1,h);
                                map->setY(j+0.9,i+0.1,h);
                                map->setY(j+0.1,i-0.1,h);
                                map->setY(j+0.1,i+0.1,h);
                                
                            
                        }

} 

void Selection::function(MadMap *map, MadMap *undomap, int type, double val)
{

//double h;
    if (!applied) { applied=true; map->copy(undomap);}
            switch (type) {
                    
                    case LEVEL:
                        
                        level(map, val/10);
                        incline(map, 0);
                        slide(map, +0.0);
                            break;
                    case SLIDE:
        
                        slide(map, val/10);
                        break;
                                
                    case INCLINE:
                        if (first.X-last.X!=first.Z-last.Z) 
                            { incline(map, val/100); slide(map, +0.0);}
                        break;
                    
                    case FLAT:
                        flat(map,map->getY((last.X+first.X)/2,(last.Z+first.Z)/2)+val);
                        break;
                
                    case UP:
                        up(map,val);
                        break;
                    case ZERO:
                        zero(map,val);
                        break;
                    case PYRAMID:
                        if (first.X-last.X==first.Z-last.Z) {
                        pyramid(map, val/(10*(last.X-first.X)+1));
                        slide(map, +0.0);}
                    default: break;
                                    
        }
                            
}



void Selection::pyramid(MadMap *map,double k)
{
    Selection s1;

    slide(map,k);
    

    if (first.X<=last.X){
    s1.first.X=first.X+1;
    s1.last.X=last.X-1;
    s1.first.Z=first.Z+1;
    s1.last.Z=last.Z-1;

    s1.pyramid(map,k);}
    
}