/********************************************************
    © 2020 Continuum Graphics LLC. All Rights Reserved
 ********************************************************/

#if !defined _MATID_
#define _MATID_

/*
    materialID = 1.0;       // Standard Material, Reflectivity 0.04
    materialID = 2.0;       // Low Gloss Material, Reflectivity 0.02
    materialID = 3.0;       // High Gloss Material, Reflectivity 0.06
    materialID = 4.0;       // Glass, Reflectivity 0.0325
    materialID = 5.0;       // Water, Reflectivity 0.0204
    materialID = 6.0;       // Gems, Reflectivity 0.16
    materialID = 7.0;       // General Plant (No light to other side)
    materialID = 8.0;       // Translucent Plant (Light to other side, tall grass, leaves, vines)
    materialID = 9.0;       // General Subsurface
    materialID = 10.0;      // Lava
    materialID = 11.0;      // Emissive
    materialID = 12.0;      // hand
    materialID = 13.0;      // Iron, Reflectivity (230 / 255)
    materialID = 14.0;      // Gold, Reflectivity (231 / 255)
    materialID = 15.0;      // Aluminum, Reflectivity (232 / 255)
    materialID = 16.0;      // Chrome, Reflectivity (233 / 255)
    materialID = 17.0;      // Copper, Reflectivity (234 / 255)
    materialID = 18.0;      // Lead, Reflectivity (235 / 255)
    materialID = 19.0;      // Platinum, Reflectivity (236 / 255)
    materialID = 20.0;      // Silver, Reflectivity (237 / 255)
    materialID = 21.0;      // Other Metals, Reflectivity 1.0
*/

void UnpackMaterialID(float data, inout float materialID, inout float reflectivity, inout mat2x3 metalIOR) {
    materialID = round(data * 32.0);
    
    if (materialID == 1.0) reflectivity = 0.04  ; // Standard Material, Reflectivity 0.04
    if (materialID == 2.0) reflectivity = 0.02  ; // Low Gloss Material, Reflectivity 0.02
    if (materialID == 3.0) reflectivity = 0.06  ; // High Gloss Material, Reflectivity 0.06
    if (materialID == 4.0) reflectivity = 0.0325; // Glass, Reflectivity 0.0325
    if (materialID == 5.0) reflectivity = 0.0204; // Water, Reflectivity 0.0203
    if (materialID == 6.0) reflectivity = 0.016 ; // Gems, Reflectivity 0.16
    
    if (materialID == 13.0) metalIOR = mat2x3(2.9114 , 2.9497 , 2.5845 , 3.0893, 2.9318, 2.7670); // Iron
    if (materialID == 14.0) metalIOR = mat2x3(0.18299, 0.42108, 1.3734 , 3.4242, 2.3459, 1.7704); // Gold
    if (materialID == 15.0) metalIOR = mat2x3(1.3456 , 0.96521, 0.61722, 7.4746, 6.3995, 5.3031); // Aluminium
    if (materialID == 16.0) metalIOR = mat2x3(3.1071 , 3.1812 , 2.3230 , 3.3314, 3.3291, 3.1350); // Chrome
    if (materialID == 17.0) metalIOR = mat2x3(0.27105, 0.67693, 1.3164 , 3.6092, 2.6248, 2.2921); // Copper
    if (materialID == 18.0) metalIOR = mat2x3(1.9100 , 1.8300 , 1.4400 , 3.5100, 3.4000, 3.1800); // Lead
    if (materialID == 19.0) metalIOR = mat2x3(2.3757 , 2.0847 , 1.8453 , 4.2655, 3.7153, 3.1365); // Platinum
    if (materialID == 20.0) metalIOR = mat2x3(0.15943, 0.14512, 0.13547, 3.9291, 3.1900, 2.3808); // Silver
    
    if (metalIOR[0].x > 0.0) reflectivity = 0.91;
    
    if (materialID == 21.0) reflectivity = 1.0; // Other Metals, Reflectivity 1.0
}

void SetSnapIDs(inout float materialID, float reflectivity) {
    materialID = reflectivity <= 0.03 ? 2.0 : materialID;
    materialID = reflectivity > 0.03 ? 1.0 : materialID;
    materialID = reflectivity > 0.05 ? 3.0 : materialID;
    materialID = reflectivity > 0.11 ? 6.0 : materialID;

    int metalID = int(reflectivity * 255.0);

    switch(metalID) {
        case 230: materialID = 13.0; break;
        case 231: materialID = 14.0; break;
        case 232: materialID = 15.0; break;
        case 233: materialID = 16.0; break;
        case 234: materialID = 17.0; break;
        case 235: materialID = 18.0; break;
        case 236: materialID = 19.0; break;
        case 237: materialID = 20.0; break;
        case 255: materialID = 21.0; break;
    }
}

float CalculateMaterialID(float materialID, int blockID) {
    switch(blockID) {
        case 31:                        // Tall Grass
        case 37:                        // Dandelion
        case 38:                        // Rose
        case 59:                        // Wheat
        case 83:                        // Sugar Cane
        case 141:                       // Carrot
        case 142:                       // Potatoes
        case 175:                       // Double Tall Grass (bottom)
        case 176:                       // Double Tall Grass (top)
        case 18:                        // Generic leaves
        case 106:                       // Vines
        case 161:                       // New leaves
        case 256:                       // dead coral fans
        case 257:                       // dead coral
        case 111:                       // Lily pad
            materialID = 8.0; break;    // Translucent
        case 10:                        // Flowing Lava
        case 11:                        // Still Lava
            materialID = 10.0; break;   // Lava
        case 50:                        // Torch
        case 51:                        // Fire
        case 89:                        // Glowstone
        case 124:                       // Redstone Lamp
            materialID = 11.0; break;   // Emissive
        /*
        case 42:                        // Iron Block
            materialID = 12.0; break;   // Iron
        case 41:                        // Gold Block
            materialID = 13.0; break;   // Gold
        */
    }

    #if defined hand
        materialID = 12.0;
    #endif

    return materialID;
}

float PackMaterialID(float reflectivity, int blockID) {
    float materialID = 1.0;
    SetSnapIDs(materialID, reflectivity);
    return CalculateMaterialID(materialID, blockID);
}

#endif
