/*
Angry Moth
Copyright (C) 2006 Linley Henzell

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public Licence as published by
    the Free Software Foundation; either version 2 of the Licence, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public Licence for more details.

    You should have received a copy of the GNU General Public Licence
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    The GPL version 2 is included in this distribution in a file called
    LICENCE.TXT. Use any text editor or the TYPE command to read it.

    You should be able to reach me by sending an email to
    l_henzell@yahoo.com.au.

File: palette.c
History:
11/9/2005 - Version 1.0 finalised

This file contains:
 - palette and transparency stuff.
Various enums are in palette.h.

*/


#include "config.h"

#include "allegro.h"


#include "palette.h"
#include "globvars.h"

COLOR_MAP trans_table;
//COLOR_MAP trans_table2;

//int blend_function(int base, int trans, RGB *rgbl);
int blend_function(int trans, int base, RGB *rgbl);
int blend_function2(int trans, int base, RGB *rgbl);
int limit_colour(int colour_input);
void halfway_colour(int base, int target, int r, int g, int b);

RGB other_palet [1324];
RGB palet [256];
RGB palet2 [256];
//RGB light_palet [256];
//RGB dark_palet [256];
RGB other_palet2 [2048];
// what seems to be a weird bug in Allegro forces me to put padding around
//  the palet array, or it becomes corrupted. The same thing happened in
//  World of Violence and I have no idea why.

/*


IMPORTANT TO REMEMBER:

    I created the palette for the GIMP by saving a 16x16 image with all colours
    as a gif then importing the palette from that. This let me get the colours
    in the right order!


 In the GIMP, must go to image|mode|indexed colour and change the settings there.






*/


void pork_create_color_table(COLOR_MAP *table, AL_CONST PALETTE pal);
void pork_create_color_table2(COLOR_MAP *table, AL_CONST PALETTE pal);
int base_colour(int y);

void colour_table(const char *which_call);


/*
Colour scheme:
Qn - how to leave space for zero? Answer: don't include outline in lights!

Base colours:
0 outline
1 lower bg 1 - Dark
2 lower bg 2 - Red
3 lower bg 3 - Yellow
4 upper bg 1 - LBlue-grey
5 upper bg 2 - DBlue-grey
6 upper bg 3 - Brown
7 Red 1 (orangish)
8 Red 2
9 Blue 1
10 Blue 2
11 Yellow 1
12 White 1
13 White 2
14 White 3 (dgrey)
15 Green 2

I can probably get away with changing these between levels, anyway.

Trans colours:
0 base

1 White
2 Yellow

3 LBlue
4 LRed
5 LGreen
6 LPurple

7 DBlue
8 Dred
9 Dgreen
10 DPurple

11 DDred

12 Black

13 Light 1
14 Light 2
15 Light 3





*/

/*
Base colours:
0 outline
1 lower bg 1 - Dark
2 lower bg 2 - Red
3 lower bg 3 - Yellow
4 upper bg 1 - LBlue-grey
5 upper bg 2 - DBlue-grey
6 upper bg 3 - Brown
7 Red 1 (orangish)
8 Red 2
9 Blue 1
10 Blue 2
11 Yellow 1
12 White 1
13 White 2
14 White 3 (dgrey)
15 Green 2
*/

int base_palette [16] [3] =
{
// Outline
{5, 5, 5}, // 1
//{16, 16, 16}, // 2
//{25, 10, 10}, // 3
//{20, 20, 5}, // 4
{9, 9, 9}, // 2
{16, 9, 9}, // 3
{13, 13, 9}, // 4
{14, 20, 14}, // 5
{14, 14, 14}, // 6
{5, 5, 24}, // 7

{50, 15, 15}, // 8
{40, 8, 8}, // 9
{20, 20, 50}, // 10
{15, 15, 35}, // 11
{48, 42, 12}, // 12
{52, 52, 52}, // 13
{36, 36, 36}, // 14
{25, 25, 25}, // 15
{2, 30, 2}, // 16


/*
{5, 5, 5}, // 1
//{16, 16, 16}, // 2
//{25, 10, 10}, // 3
//{20, 20, 5}, // 4
{9, 9, 9}, // 2
{13, 13, 13}, // 3
{12, 12, 12}, // 4
{17, 17, 17}, // 5
{21, 21, 21}, // 6
{12, 12, 12}, // 7
{40, 40, 40}, // 8
{20, 20, 20}, // 9
{35, 35, 35}, // 10
{22, 22, 22}, // 11
{39, 38, 39}, // 12
{52, 52, 52}, // 13
{36, 36, 36}, // 14
{25, 25, 25}, // 15
{16, 16, 16}, // 16*/


};

int stage2_palette [16] [3] =
{
// Outline
{5, 5, 5}, // 1

{0, 10, 0}, // 5
{0, 20, 0}, // 6
{0, 30, 0}, // 7

{8, 8, 0}, // 2
{19, 19, 2}, // 3
{27, 27, 4}, // 4

{50, 15, 15}, // 8
{40, 8, 8}, // 9
{20, 20, 50}, // 10
{15, 15, 35}, // 11
{48, 42, 12}, // 12
{52, 52, 52}, // 13
{36, 36, 36}, // 14
{25, 25, 25}, // 15
{2, 30, 2}, // 16
//{12, 32, 12}, //


};



#define END_TRANSPARENCIES 104


void reset_palette(void)
{
 vsync();
 set_palette(palet);
}

void init_palette(void)
{

int i;

 palet [0].r = 0;
 palet [0].g = 0;
 palet [0].b = 0;

 for (i = 0; i < 256; i ++)
 {

     palet [i].r = 0;
     palet [i].g = 0;
     palet [i].b = 0;

  }

// struct pstruct *bpal [16] = base_palette;
// RGB *pal2 = palet;

 for (i = 1; i < 17; i ++)
 {

     palet [i].r = base_palette [i - 1] [0];
     palet [i].g = base_palette [i - 1] [1];
     palet [i].b = base_palette [i - 1] [2];

 }




 for (i = 0; i < 16; i ++)
 {

    palet[i + TRANS_WHITE].r = limit_colour(base_palette [i] [0] / 3 + 54);
    palet[i + TRANS_WHITE].g = limit_colour(base_palette [i] [1] / 3 + 54);
    palet[i + TRANS_WHITE].b = limit_colour(base_palette [i] [2] / 3 + 54);

    palet[i + TRANS_YELLOW].r = limit_colour(base_palette [i] [0] / 4 + 45);
    palet[i + TRANS_YELLOW].g = limit_colour(base_palette [i] [1] / 4 + 36);
    palet[i + TRANS_YELLOW].b = limit_colour(base_palette [i] [2] / 4);

    palet[i + TRANS_LBLUE].r = limit_colour(base_palette [i] [0] / 3 + 20);
    palet[i + TRANS_LBLUE].g = limit_colour(base_palette [i] [1] / 3 + 20);
    palet[i + TRANS_LBLUE].b = limit_colour(base_palette [i] [2] / 3 + 40);

    palet[i + TRANS_LGREEN].r = limit_colour(base_palette [i] [0] / 3 + 5);
    palet[i + TRANS_LGREEN].g = limit_colour(base_palette [i] [1] / 3 + 30);
    palet[i + TRANS_LGREEN].b = limit_colour(base_palette [i] [2] / 3 + 5);

    palet[i + TRANS_LRED].r = limit_colour(base_palette [i] [0] / 2 + 36);
    palet[i + TRANS_LRED].g = limit_colour(base_palette [i] [1] / 2 + 10);
    palet[i + TRANS_LRED].b = limit_colour(base_palette [i] [2] / 2 + 0);
/*    palet[i + TRANS_LRED].r = limit_colour(base_palette [i] [0] / 3 + 36);
    palet[i + TRANS_LRED].g = limit_colour(base_palette [i] [1] / 3 + 20);
    palet[i + TRANS_LRED].b = limit_colour(base_palette [i] [2] / 3 + 0);*/


    palet[i + TRANS_LPURPLE].r = limit_colour(base_palette [i] [0] / 2 + 30);
    palet[i + TRANS_LPURPLE].g = limit_colour(base_palette [i] [1] / 2 + 0);
    palet[i + TRANS_LPURPLE].b = limit_colour(base_palette [i] [2] / 2 + 40);

    palet[i + TRANS_DBLUE].r = limit_colour(base_palette [i] [0] / 2 + 5);
    palet[i + TRANS_DBLUE].g = limit_colour(base_palette [i] [1] / 2 + 5);
    palet[i + TRANS_DBLUE].b = limit_colour(base_palette [i] [2] / 2 + 35);

    palet[i + TRANS_DPURPLE].r = limit_colour(base_palette [i] [0] / 2 + 20);
    palet[i + TRANS_DPURPLE].g = limit_colour(base_palette [i] [1] / 2 + 0);
    palet[i + TRANS_DPURPLE].b = limit_colour(base_palette [i] [2] / 2 + 30);

    palet[i + TRANS_DGREEN].r = limit_colour(base_palette [i] [0] / 2 + 0);
    palet[i + TRANS_DGREEN].g = limit_colour(base_palette [i] [1] / 2 + 15);
    palet[i + TRANS_DGREEN].b = limit_colour(base_palette [i] [2] / 2 + 0);

    palet[i + TRANS_DRED].r = limit_colour(base_palette [i] [0] / 2 + 25);
    palet[i + TRANS_DRED].g = limit_colour(base_palette [i] [1] / 2 + 0);
    palet[i + TRANS_DRED].b = limit_colour(base_palette [i] [2] / 2 + 0);

    palet[i + TRANS_DDRED].r = limit_colour(base_palette [i] [0] + 12);
    palet[i + TRANS_DDRED].g = limit_colour(base_palette [i] [1] - 0);
    palet[i + TRANS_DDRED].b = limit_colour(base_palette [i] [2] - 0);

    palet[i + TRANS_BLACK].r = limit_colour(base_palette [i] [0] - 15);
    palet[i + TRANS_BLACK].g = limit_colour(base_palette [i] [1] - 15);
    palet[i + TRANS_BLACK].b = limit_colour(base_palette [i] [2] - 15);

    palet[i + TRANS_DDBLUE].r = limit_colour(base_palette [i] [0] + 3);
    palet[i + TRANS_DDBLUE].g = limit_colour(base_palette [i] [1] + 3);
    palet[i + TRANS_DDBLUE].b = limit_colour(base_palette [i] [2] + 20);

    palet[i + TRANS_DDGREEN].r = limit_colour(base_palette [i] [0] + 0);
    palet[i + TRANS_DDGREEN].g = limit_colour(base_palette [i] [1] + 9);
    palet[i + TRANS_DDGREEN].b = limit_colour(base_palette [i] [2] + 0);

 }

  palet[0].r = 0;
  palet[0].g = 0;
  palet[0].b = 0;







// **********************************************************************88

// start palet2

// **********************************************************************88

 palet2 [0].r = 0;
 palet2 [0].g = 0;
 palet2 [0].b = 0;

 for (i = 0; i < 256; i ++)
 {

     palet2 [i].r = 0;
     palet2 [i].g = 0;
     palet2 [i].b = 0;

  }

// struct pstruct *bpal [16] = base_palet2te;
// RGB *pal2 = palet2;

 for (i = 1; i < 17; i ++)
 {

     palet2 [i].r = stage2_palette [i - 1] [0];
     palet2 [i].g = stage2_palette [i - 1] [1];
     palet2 [i].b = stage2_palette [i - 1] [2];

 }




 for (i = 0; i < 16; i ++)
 {

    palet2[i + TRANS_WHITE].r = limit_colour(stage2_palette [i] [0] / 3 + 54);
    palet2[i + TRANS_WHITE].g = limit_colour(stage2_palette [i] [1] / 3 + 54);
    palet2[i + TRANS_WHITE].b = limit_colour(stage2_palette [i] [2] / 3 + 54);

    palet2[i + TRANS_YELLOW].r = limit_colour(stage2_palette [i] [0] / 4 + 45);
    palet2[i + TRANS_YELLOW].g = limit_colour(stage2_palette [i] [1] / 4 + 36);
    palet2[i + TRANS_YELLOW].b = limit_colour(stage2_palette [i] [2] / 4);

    palet2[i + TRANS_LBLUE].r = limit_colour(stage2_palette [i] [0] / 3 + 20);
    palet2[i + TRANS_LBLUE].g = limit_colour(stage2_palette [i] [1] / 3 + 20);
    palet2[i + TRANS_LBLUE].b = limit_colour(stage2_palette [i] [2] / 3 + 40);

    palet2[i + TRANS_LGREEN].r = limit_colour(stage2_palette [i] [0] / 3 + 5);
    palet2[i + TRANS_LGREEN].g = limit_colour(stage2_palette [i] [1] / 3 + 30);
    palet2[i + TRANS_LGREEN].b = limit_colour(stage2_palette [i] [2] / 3 + 5);

/*    palet2[i + TRANS_LRED].r = limit_colour(stage2_palette [i] [0] / 3 + 36);
    palet2[i + TRANS_LRED].g = limit_colour(stage2_palette [i] [1] / 3 + 20);
    palet2[i + TRANS_LRED].b = limit_colour(stage2_palette [i] [2] / 3 + 0);*/
    palet2[i + TRANS_LRED].r = limit_colour(stage2_palette [i] [0] / 2 + 36);
    palet2[i + TRANS_LRED].g = limit_colour(stage2_palette [i] [1] / 2 + 10);
    palet2[i + TRANS_LRED].b = limit_colour(stage2_palette [i] [2] / 2 + 0);

    palet2[i + TRANS_LPURPLE].r = limit_colour(stage2_palette [i] [0] / 2 + 30);
    palet2[i + TRANS_LPURPLE].g = limit_colour(stage2_palette [i] [1] / 2 + 0);
    palet2[i + TRANS_LPURPLE].b = limit_colour(stage2_palette [i] [2] / 2 + 40);

    palet2[i + TRANS_DBLUE].r = limit_colour(stage2_palette [i] [0] / 2 + 5);
    palet2[i + TRANS_DBLUE].g = limit_colour(stage2_palette [i] [1] / 2 + 5);
    palet2[i + TRANS_DBLUE].b = limit_colour(stage2_palette [i] [2] / 2 + 35);

    palet2[i + TRANS_DPURPLE].r = limit_colour(stage2_palette [i] [0] / 2 + 20);
    palet2[i + TRANS_DPURPLE].g = limit_colour(stage2_palette [i] [1] / 2 + 0);
    palet2[i + TRANS_DPURPLE].b = limit_colour(stage2_palette [i] [2] / 2 + 30);

    palet2[i + TRANS_DGREEN].r = limit_colour(stage2_palette [i] [0] / 2 + 0);
    palet2[i + TRANS_DGREEN].g = limit_colour(stage2_palette [i] [1] / 2 + 15);
    palet2[i + TRANS_DGREEN].b = limit_colour(stage2_palette [i] [2] / 2 + 0);

    palet2[i + TRANS_DRED].r = limit_colour(stage2_palette [i] [0] / 2 + 25);
    palet2[i + TRANS_DRED].g = limit_colour(stage2_palette [i] [1] / 2 + 5);
    palet2[i + TRANS_DRED].b = limit_colour(stage2_palette [i] [2] / 2 + 5);

    palet2[i + TRANS_DDRED].r = limit_colour(stage2_palette [i] [0] + 12);
    palet2[i + TRANS_DDRED].g = limit_colour(stage2_palette [i] [1] + 3);
    palet2[i + TRANS_DDRED].b = limit_colour(stage2_palette [i] [2] + 3);

    palet2[i + TRANS_BLACK].r = limit_colour(stage2_palette [i] [0] + 15);
    palet2[i + TRANS_BLACK].g = limit_colour(stage2_palette [i] [1] + 15);
    palet2[i + TRANS_BLACK].b = limit_colour(stage2_palette [i] [2] + 15);
    /*    palet2[i + TRANS_BLACK].r = limit_colour(stage2_palette [i] [0] - 15);
    palet2[i + TRANS_BLACK].g = limit_colour(stage2_palette [i] [1] - 15);
    palet2[i + TRANS_BLACK].b = limit_colour(stage2_palette [i] [2] - 15);*/

    palet2[i + TRANS_DDBLUE].r = limit_colour(stage2_palette [i] [0] + 3);
    palet2[i + TRANS_DDBLUE].g = limit_colour(stage2_palette [i] [1] + 3);
    palet2[i + TRANS_DDBLUE].b = limit_colour(stage2_palette [i] [2] + 20);

    palet2[i + TRANS_DDGREEN].r = limit_colour(stage2_palette [i] [0] + 0);
    palet2[i + TRANS_DDGREEN].g = limit_colour(stage2_palette [i] [1] + 9);
    palet2[i + TRANS_DDGREEN].b = limit_colour(stage2_palette [i] [2] + 0);

 }

  palet2[0].r = 0;
  palet2[0].g = 0;
  palet2[0].b = 0;

// end palet2



   vsync();
   set_palette(palet);

   pork_create_color_table(&trans_table, palet);

//   pork_create_color_table2(&trans_table2, palet);

   color_map = &trans_table;

//   set_palette(palet2);

}


void halfway_colour(int base, int target, int r, int g, int b)
{

    int diff;

    diff = palet[base].r - r;
    diff /= 2;
    palet[target].r += diff;

    diff = palet[base].g - g;
    diff /= 2;
    palet[target].g += diff;

    diff = palet[base].b - b;
    diff /= 2;
    palet[target].b += diff;

}


int limit_colour(int colour_input)
{

 if (colour_input < 0) return 0;
 if (colour_input > 63) return 63;
 return colour_input;

}

/*
int blend_function(int trans, int base, RGB *rgbl)
{

 if (base <= COLOUR_11)
  return trans + base;

// int low_colour = base % 12;
// int low_trans = trans / 12;
 int trans_strength = (trans / 12 - 1) % 6;

 if (trans == TRANS_PURPLE1)
  trans_strength = 10;
 if (trans == TRANS_PURPLE2)
  trans_strength = 11;

 int base_trans_strength = (base / 12 - 1) % 6;
 if (trans == TRANS_PURPLE1)
  base_trans_strength = 10;
 if (trans == TRANS_PURPLE2)
  base_trans_strength = 11;

 if (trans_strength >= base_trans_strength)
  return trans + (base % 12);
   else return base;

 return trans;

}
*/

int blend_function(int trans, int base, RGB *rgbl)
{

// base = COLOUR_12 = 12
// trans = TRANS_WHITE1 = 13
// trans + base = 25
// trans + base - 1 = 24
/*
 if (trans == CONVERT_POLE)
 {
  switch(base)
  {
   case 2: return 12;
   case 3: return 11;
   case 4: return 10;
   case 10: return 4;
   case 11: return 3;
   case 12: return 2;
   default: return base;
  }
 }
*/
/*
 if (trans == FIX_BITMAP)
 {
  switch(base)
  {
   case 1: return 0;
   case 5:
   case 6: return 9;
   case 4: return 10;
   case 2: return 12;
   case 3: return 12;
   default: return base;
  }
 }
*/
 //if (base == COLOUR_12)
  //return trans + base - 1;

 //if (base <= COLOUR_12)
  //return trans + base - 1;

//  return trans + ((base) % 12);
//// return base;

// trans --;



/*

    if (trans == TRANS_LIGHT1
        || trans == TRANS_LIGHT2
        || trans == TRANS_LIGHT3)
    {
        if (base == COL_OUTLINE)
         return COL_OUTLINE; // don't light up outline; this lets us cram more trans colours in

        if (base < TRANS_LIGHT1)
         return (base + trans - 2) % 0xFF; // the % 0xFF is just to make sure it doesn't break the array limits. Any number which is > 255 isn't used.

        trans -= TRANS_LIGHT1;
        base -= TRANS_LIGHT1;

        if (trans > base)
         return base;

        return trans + base % 15;

    }*/

 if (base < TRANS_WHITE)
  return trans + base - 1;

 int trans_strength = (trans - 1) / 16;

// if (trans == TRANS_PURPLE1)
//  trans_strength = 10;
 //if (trans == TRANS_PURPLE2)
  //trans_strength = 11;

 int base_trans_strength = (base - 1) / 16;

 if (trans_strength <= base_trans_strength)
  return trans + ((base - 1) % 16);
   else return base;

 return trans;

}



/*int blend_function(int trans, int base, RGB *rgbl)
{

 if (base <= COLOUR_12)
  return trans + base;

 trans --;

// int low_colour = base % 12;
// int low_trans = trans / 12;
 int trans_strength = (trans / 12 - 1) % 6;

 if (trans == TRANS_PURPLE1)
  trans_strength = 10;
 if (trans == TRANS_PURPLE2)
  trans_strength = 11;

 int base_trans_strength = (base / 12 - 1) % 6;
 if (trans == TRANS_PURPLE1)
  base_trans_strength = 10;
 if (trans == TRANS_PURPLE2)
  base_trans_strength = 11;

 if (trans_strength >= base_trans_strength)
  return trans + (base % 12);
   else return base;

 return trans;

}
*/
/*
This function had to be modified from the allegro create_color_table
because the allegro version used bestfit_color, whereas we need
specific color values
*/
void pork_create_color_table(COLOR_MAP *table, AL_CONST PALETTE pal)
{
   int x, y, z;
   RGB c;

   for (x=0; x<PAL_SIZE; x++) {
      for (y=0; y<PAL_SIZE; y++) {
   z = blend_function(x, y, &c);

      table->data[x][y] = z;
      }

   }
}


