// Script to present a dialog populated with a list of notecards
// from the prims inventory
//
// Note that only the first 24 characters of the notecard names
// are actually used - as only 24 chars can be placed in a dialog
// button.  This means that if two notecards have the first 24 chars
// the same, the second will be ignored ...
//
// Note however that usually, buttons don't display more than, say,
// around 10 or so characters anyway!!
//
// Kimm Paulino
// Written for Vikki Hastings, June 2011
 
// Configure the behaviour we want
string  gFloatingText = "Click for notecards";  // Set to "" to disable
vector  gFloatingTextColour = <1.0, 1.0, 1.0>;
float   gFloatingTextAlpha = 1.0;
 
integer gChannel;
integer gMenuPage;
integer gNumNotecards;
list gNotecards;
 
string MENU_NEXT="Next>";
string MENU_TOP="Top";
string MENU_BACK="= num_pages)
    {
        // gMenuPage is an index starting at 0...
        // max is a 1...
        gMenuPage = num_pages-1;
    }
 
    // Note: This yields notecards counting as follows:
    // 0 to 8 = first page,
    // 9 to 17 = next page, etc
    integer first_nc = gMenuPage * 9;
    integer last_nc = first_nc + 9 - 1;
    if (last_nc >= gNumNotecards)
    {
        // recall last_nc indexed from 0, but
        // gNumNotecards is indexed from 1
        last_nc = gNumNotecards-1;
    }
 
//    llOwnerSay ("Menu Page: " + (string)gMenuPage);
//    llOwnerSay ("First NC: " + (string)first_nc);
//    llOwnerSay ("Last NC: " + (string)last_nc);
 
    if (gMenuPage > 0)
    {
        buttons += [MENU_BACK];
    }
    else
    {
        buttons += [MENU_SPACE];
    }
 
    if (gMenuPage == 0)
    {
        buttons += [MENU_SPACE];
    }
    else
    {
 
        buttons += [MENU_TOP];
    }
 
    // If not on the last page, and there are more pages to come ...
    if (gNumNotecards > 9 && gMenuPage < (num_pages-1))
    {
        buttons += [MENU_NEXT];
    }
    else
    {
        buttons += [MENU_SPACE];
    }
 
    integer i;
    for (i=first_nc; (i <= last_nc) && (i < gNumNotecards); i++)
    {
        buttons += [llList2String (gNotecards, i)];
    }
 
    llDialog (id, "\n\n(click \"Ignore\" when done)", buttons, gChannel);
}
 
default
{
    on_rez (integer start_param)
    {
        llResetScript();
    }
 
    state_entry()
    {
        llSetText (gFloatingText, gFloatingTextColour, gFloatingTextAlpha);
        read_notecards();
        gMenuPage = 0;
        gChannel = getRandomChannel();
 
        // Would be less laggy to close listen when not in use
        // but then if two people attempted to use the giver,
        // it wouldn't be able to cope.  This way, they can both
        // use it at the same time ...
        llListen (gChannel, "", "", ""); 
    }
 
    touch_start(integer total_number)
    {
        // Start menu system again. Note that I don't do anything special
        // with several people trying to touch it at the same time - it will
        // always overlap the processing of gMenuPage, but all that will
        // happen is that peoples next/back might be a bit quirky for a while.
        // Eventually, they will sort themselves out!
        gMenuPage = 0;
        show_dialog (llDetectedKey(0));
    }
 
    listen (integer channel, string name, key id, string msg)
    {
        if (channel == gChannel)
        {
            if (msg == MENU_BACK)
            {
                gMenuPage--;
                show_dialog (id);
            }
            else if (msg == MENU_TOP)
            {
                gMenuPage = 0;
                show_dialog (id);
            }
            else if (msg == MENU_NEXT)
            {
                gMenuPage++;
                show_dialog (id);
            }            
            else
            {
                // should be something in the inventory to give out
                give_notecard (id, msg);
            }
        }
    }
 
    changed (integer change)
    {
        if (change & CHANGED_INVENTORY)
        {
            llResetScript();
        }
    }
}