//////////////////////////////////////////////////////////////////////
// Simple tool to help texture the inside of a hollowed cube.
// By Antony Fairport.
//
// Based on a comment in
//    https://jira.secondlife.com/browse/VWR-2397?
// found via
//    http://monaeberhardt.wordpress.com/2013/12/03/how-to-get-texture-repeats-on-the-inside-of-a-hollow-prim-right/
//
// Notes:
// The calculation given in the above has been tested with and found
// not to work so well with the following prim types:
//
// PRIM_TYPE_PRISM
// PRIM_TYPE_SPHERE

//////////////////////////////////////////////////////////////////////
// Are we supporting this shape type?
integer SupportedShape( integer iShape )
{
    return ( iShape == PRIM_TYPE_BOX ) || ( iShape == PRIM_TYPE_CYLINDER );
}

//////////////////////////////////////////////////////////////////////
// Return the number of the inside face, depending on shape.
integer InsideFace( integer iShape )
{
    if ( iShape == PRIM_TYPE_CYLINDER )
    {
        return 2;
    }
    else
    {
        // Assume it's a box.
        return 5;
    }
}

//////////////////////////////////////////////////////////////////////
// Turn a hollow shape into something more useful than "Default".
integer UnDefaultHollow( integer iPrimShape, integer iHollowShape )
{
    if ( iHollowShape == PRIM_HOLE_DEFAULT )
    {
        if ( iPrimShape == PRIM_TYPE_BOX )
        {
            iHollowShape = PRIM_HOLE_SQUARE;
        }
        else if ( iPrimShape == PRIM_TYPE_CYLINDER )
        {
            iHollowShape = PRIM_HOLE_CIRCLE;
        }
    }
    
    return iHollowShape;
}

//////////////////////////////////////////////////////////////////////
// Infer a desired repeat based on the hollow shape.
integer InferDesiredRepeat( integer iHollowShape )
{
    // Circle?
    if ( iHollowShape == PRIM_HOLE_CIRCLE )
    {
        // Assume just the one repeat.
        return 1;
    }
    // Triangle?
    else if ( iHollowShape == PRIM_HOLE_TRIANGLE )
    {
        // Assume 3 -- one per "face".
        return 3;
    }
    else
    {
        // Otherwise it's a square.
        return 4;
    }
}

//////////////////////////////////////////////////////////////////////
// Repaint the inside face of the hollow.
RePaint()
{
    // Get the details of the prim we're on.
    list    lParams    = llGetPrimitiveParams( [ PRIM_TYPE ] );
    integer iPrimShape = llList2Integer( lParams, 0 );
    
    // Is it a supported shape?
    if ( SupportedShape( iPrimShape ) )
    {
        // Get the details of the hollow.
        integer iHollowShape = llList2Integer( lParams, 1 );
        float   nHollowSize  = llList2Float( lParams, 3 );
        
        // If it looks like we're hollow...
        if ( nHollowSize > 0.01 )
        {
            // Infer the desired repeat from the hollow shape.
            integer nDesiredRepeat = InferDesiredRepeat( UnDefaultHollow( iPrimShape, iHollowShape ) );
            
            float nRepeat = nDesiredRepeat / nHollowSize;
            float nOffset = ( ( nDesiredRepeat / nHollowSize ) - nDesiredRepeat ) / 2.0;
            
            llScaleTexture( -nRepeat, 1.0, InsideFace( iPrimShape ) );
            llOffsetTexture( -( nOffset - (integer) nOffset ), 1.0, InsideFace( iPrimShape ) );
        }
    }
    else
    {
        llSay( 0, "Sorry, this prim shape isn't supported." );
    }
}

//////////////////////////////////////////////////////////////////////
// Default state.
default
{
    //////////////////////////////////////////////////////////////////
    // Repaint when we get dropped into the prim.
    state_entry()
    {
        RePaint();
    }
        
    //////////////////////////////////////////////////////////////////
    // React to changes.
    changed( integer change )
    {
        // If the shape has changed....
        if ( change & CHANGED_SHAPE )
        {
            // ...it could mean the hollow has. Repaint.
            RePaint();
        }
    }
}