ampoule_bifocal_stereopticon.lsl
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueGet(string var, string kvp) {
    list dVars = llParseString2List(kvp, ["&"], []);
    do {
        list data = llParseString2List(llList2String(dVars, 0), ["="], []);
        string k = llList2String(data, 0);
        if(k != var) jump continue;
        return llList2String(data, 1);
@continue;
        dVars = llDeleteSubList(dVars, 0, 0);
    } while(llGetListLength(dVars));
    return "";
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueSet(string var, string val, string kvp) {
    list dVars = llParseString2List(kvp, ["&"], []);
    if(llGetListLength(dVars) == 0) return var + "=" + val;
    list result = [];
    do {
        list data = llParseString2List(llList2String(dVars, 0), ["="], []);
        string k = llList2String(data, 0);
        if(k == "") jump continue;
        if(k == var && val == "") jump continue;
        if(k == var) {
            result += k + "=" + val;
            val = "";
            jump continue;
        }
        string v = llList2String(data, 1);
        if(v == "") jump continue;
        result += k + "=" + v;
@continue;
        dVars = llDeleteSubList(dVars, 0, 0);
    } while(llGetListLength(dVars));
    if(val != "") result += var + "=" + val;
    return llDumpList2String(result, "&");
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
vector wasStringToVector(string in) {
    list v = llParseString2List(in, ["<", ",", ">"], []);
    return <llList2Float(v, 0), llList2Float(v, 1), llList2Float(v, 2)>;
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
integer wasMenuIndex = 0;
list wasDialogMenu(list input, list actions, string direction) {
    integer cut = 11-wasListCountExclude(actions, [""]);
    if(direction == ">" &&  (wasMenuIndex+1)*cut+wasMenuIndex+1 < llGetListLength(input)) {
        ++wasMenuIndex;
        jump slice;
    }
    if(direction == "<" && wasMenuIndex-1 >= 0) {
        --wasMenuIndex;
        jump slice;
    }
@slice;
    integer multiple = wasMenuIndex*cut;
    input = llList2List(input, multiple+wasMenuIndex, multiple+cut+wasMenuIndex);
    input = wasListMerge(input, actions, "");
    return input;
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
integer wasListCountExclude(list input, list exclude) {
    if(llGetListLength(input) == 0) return 0;
    if(llListFindList(exclude, (list)llList2String(input, 0)) == -1) 
        return 1 + wasListCountExclude(llDeleteSubList(input, 0, 0), exclude);
    return wasListCountExclude(llDeleteSubList(input, 0, 0), exclude);
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
list wasListMerge(list l, list m, string merge) {
    if(llGetListLength(l) == 0 && llGetListLength(m) == 0) return [];
    string a = llList2String(m, 0);
    if(a != merge) return [ a ] + wasListMerge(l, llDeleteSubList(m, 0, 0), merge);
    return [ llList2String(l, 0) ] + wasListMerge(llDeleteSubList(l, 0, 0), llDeleteSubList(m, 0, 0), merge);
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasProgress(integer percent, integer length, list symbols) {
    percent /= (integer)((float)100.0/(length));
    string p = llList2String(symbols,0);
    integer itra = 0;
    do {
        if(itra>percent-1) p += llList2String(symbols,2);
        else p += llList2String(symbols,1);
    } while(++itra<length);
    return p + llList2String(symbols,3);
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
vector wasPercentToGradient(float percent, string rgb) {
    if(llStringLength(rgb) != 2) {
        llSay(DEBUG_CHANNEL, "Assert failed, rgb parameter must consist of a pair of either r, g, or b.");
        return ZERO_VECTOR;
    }
    string a = llGetSubString(rgb, 0, 0);
    string b = llGetSubString(rgb, 1, 1);
    list col = [ "r", "g", "b" ];
    integer ax = llListFindList(col, (list)a);
    integer bx = llListFindList(col, (list)b);
    if(ax == -1 || bx == -1) {
        llSay(DEBUG_CHANNEL, "Asset failed, rgb parameters must contain either r, g, or b letters.");
        return ZERO_VECTOR;
    }
    col = llListReplaceList(col, (list)((100-percent)/100), ax, ax);
    col = llListReplaceList(col, (list)(percent/100), bx, bx);
    return 2*<llList2Float(col, 0), llList2Float(col, 1), llList2Float(col, 2)>;
}
 
ABS(key id) {
    if(id != NULL_KEY && llGetAttached() != 0) {
        vector n = llList2Vector(llGetLinkPrimitiveParams(48, [PRIM_COLOR, ALL_SIDES]), 0);
        llOwnerSay("@setenv_ambientr:" + (string)n.x + "=force");
        llOwnerSay("@setenv_ambientg:" + (string)n.y + "=force");
        llOwnerSay("@setenv_ambientb:" + (string)n.z + "=force");
        return;
    }
    llOwnerSay("@setenv_daytime:-1=force");
}
 
integer i = 0;
integer channel = 0;
key toucher = NULL_KEY;
list monogram = [];
 
default {
    state_entry() {
        if(wasKeyValueGet("auto", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "on") llSensorRepeat("", "", AGENT, 3, TWO_PI, 3);
        ABS(llGetOwner());
        if(toucher == NULL_KEY) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0\n\nFocal: " + wasKeyValueGet("auto", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)), ["◯ Open", "◉ Closed", "⎙ Options"], channel);
    }
    touch_start(integer total_number) {
        toucher = llDetectedKey(0);
        channel = (integer)("0x8" + llGetSubString(toucher, 0, 6));
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0\n\nFocal: " + wasKeyValueGet("auto", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)), ["◯ Open", "◉ Closed", "⎙ Options"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "◯ Open") {
            if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "open") return;
            llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
            llSetTimerEvent(.5);
            llListenRemove(i);
            return;
        }
        if(message == "◉ Closed") {
            if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "closed") return;
            llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
            llSetTimerEvent(.5);
            llListenRemove(i);
            return;
        }
// REGION: OWNER
        if(toucher != llGetOwner()) {
            llInstantMessage(toucher, "Sorry, this option is restricted to the owner.");
            llListenRemove(i);
            return;
        }
        if(message == "⎙ Options") state options;
// REGION: OWNER
    }
    sensor(integer num) {
        if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "closed") return;
        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
        llSetTimerEvent(.5);
    }
    no_sensor() {
        if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "open") return;
        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
        llSetTimerEvent(.5);
    }
    run_time_permissions(integer perm) {
        if(!(perm & PERMISSION_TRIGGER_ANIMATION)) return;
        if(llGetInventoryType("Glasses") != INVENTORY_ANIMATION) return;
        llStartAnimation("Glasses");
    }
    timer() {
        if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "open") {
            llSetLinkPrimitiveParamsFast(2, [PRIM_TYPE, PRIM_TYPE_CYLINDER, PRIM_HOLE_CIRCLE, <0, 1, 0>, 0, ZERO_VECTOR, <1, 1, 0>, ZERO_VECTOR, PRIM_SLICE, <0, .1, 0>]);
            llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("status", "closed", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]);
            jump reset;
        }
        llSetLinkPrimitiveParamsFast(2, [PRIM_TYPE, PRIM_TYPE_CYLINDER, PRIM_HOLE_CIRCLE, <0, 1, 0>, .85, ZERO_VECTOR, <1, 1, 0>, ZERO_VECTOR,PRIM_SLICE, <0, .1, 0>]);
        llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("status", "open", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]);
@reset;
        llResetScript();
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}
 
state options {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "⎙ Color", "⎙ Opacity", "⎙ Bright", "⎙ Glow", "⎙ Size", "⎙ Focal", "⎙ Stamp"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "⎙ Color", "⎙ Opacity", "⎙ Bright", "⎙ Glow", "⎙ Size", "⎙ Focal", "⎙ Stamp"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") state default;
        if(message == "⎙ Color") state color;
        if(message == "⎙ Opacity") state opacity;
        if(message == "⎙ Bright") state bright;
        if(message == "⎙ Glow") state glow;
        if(message == "⎙ Size") state size;
        if(message == "⎙ Focal") state auto;
        if(message == "⎙ Stamp") state read_monogram;
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}
 
state color {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") state options;
        list params = llGetLinkPrimitiveParams(48, [PRIM_COLOR, ALL_SIDES]);
        vector color = llList2Vector(params, 0);
        float alpha = llList2Float(params, 1);
        vector n = ZERO_VECTOR;
        if(message == "R ▼") {
            n = color-<.1,0,0>;
            llSetLinkPrimitiveParamsFast(48, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            jump set;
        }
        if(message == "R ▲") {
            n = color+<.1,0,0>;
            llSetLinkPrimitiveParamsFast(48, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            jump set;
        }
        if(message == "G ▼") {
            n = color-<0,.1,0>;
            llSetLinkPrimitiveParamsFast(48, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            jump set;
        }
        if(message == "G ▲") {
            n = color+<0,.1,0>;
            llSetLinkPrimitiveParamsFast(48, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            jump set;
        }
        if(message == "B ▼") {
            n = color-<0,0,.1>;
            llSetLinkPrimitiveParamsFast(48, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            jump set;
        }
        if(message == "B ▲") {
            n = color+<0,0,.1>;
            llSetLinkPrimitiveParamsFast(48, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_COLOR, ALL_SIDES, n, alpha]);
            jump set;
        }
@set;
        llOwnerSay("@setenv_ambientr:" + (string)n.x + "=force");
        llOwnerSay("@setenv_ambientg:" + (string)n.y + "=force");
        llOwnerSay("@setenv_ambientb:" + (string)n.z + "=force");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel);
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}
 
state opacity {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "Opacity ▼", "Opacity ▲"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "Opacity ▼", "Opacity ▲"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") state options;
        list params = llGetLinkPrimitiveParams(48, [PRIM_COLOR, ALL_SIDES]);
        vector color = llList2Vector(params, 0);
        float alpha = llList2Float(params, 1);
        if(message == "Opacity ▼") {
            llSetLinkPrimitiveParamsFast(48, [PRIM_COLOR, ALL_SIDES, color, alpha-.1]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_COLOR, ALL_SIDES, color, alpha-.1]);
            jump menu;
        }
        if(message == "Opacity ▲") {
            llSetLinkPrimitiveParamsFast(48, [PRIM_COLOR, ALL_SIDES, color, alpha+.1]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_COLOR, ALL_SIDES, color, alpha+.1]);
            jump menu;
        }
@menu;
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "Opacity ▼", "Opacity ▲"], channel);
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}
 
state bright {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "◉ ON", "◯ OFF"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "◉ ON", "◯ OFF"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") state options;
        if(message == "◉ ON") {
            llSetLinkPrimitiveParamsFast(48, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]);
            jump menu;
        }
        if(message == "◯ OFF") {
            llSetLinkPrimitiveParamsFast(48, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);
        }
@menu;
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "◉ ON", "◯ OFF"], channel);
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}
 
state glow {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "Glow ▼", "Glow ▲"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "Glow ▼", "Glow ▲"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") state options;
        list params = llGetLinkPrimitiveParams(48, [PRIM_GLOW, ALL_SIDES]);
        float glow = llList2Float(params, 0);
        if(message == "Glow ▼") {
            if(glow - .01 < 0) jump menu;
            llSetLinkPrimitiveParamsFast(48, [PRIM_GLOW, ALL_SIDES, glow-.01]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_GLOW, ALL_SIDES, glow-.01]);
            jump menu;
        }
        if(message == "Glow ▲") {
            if(glow + .01 > 1) jump menu;
            llSetLinkPrimitiveParamsFast(48, [PRIM_GLOW, ALL_SIDES, glow+.01]);
            llSetLinkPrimitiveParamsFast(45, [PRIM_GLOW, ALL_SIDES, glow+.01]);
            jump menu;
        }
@menu;
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["⏏ Exit", "Glow ▼", "Glow ▲"], channel);
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}
 
state size {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["-.01", "-.02", "-.05", "+.01", "+.02", "+.05", "⏏ Exit"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["-.01", "-.02", "-.05", "+.01", "+.02", "+.05", "⏏ Exit"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") state options;
        if((float)message == 0) return;
        float scale = 1 + (float)message;
        integer i = llGetNumberOfPrims();
        do {
            vector linkScale = llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_SIZE]), 0);
            vector linkPos = llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_POS_LOCAL]), 0);
            llSetLinkPrimitiveParamsFast(i, [PRIM_SIZE, scale * linkScale, PRIM_POSITION, scale * linkPos]);
        } while(--i>1);
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", ["-.01", "-.02", "-.05", "+.01", "+.02", "+.05", "⏏ Exit"], channel);
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}
 
state auto {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0\n\nTurning this option on will automatically tilt the glasses up once you are standing close to an avatar and put them back down again when you move away from avatars.", ["⏏ Exit", "◉ ON", "◯ OFF" ], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0\n\nTurning this option on will automatically tilt the glasses up once you are standing close to an avatar and put them back down again when you move away from avatars.", ["⏏ Exit", "◉ ON", "◯ OFF" ], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "◉ ON") {
            llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("auto", "on", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]);
            jump options;
        }
        if(message == "◯ OFF") llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("auto", "off", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]);
@options;
        state options;
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}
 
state read_monogram {
    state_entry() {
        i = llGetInventoryNumber(INVENTORY_NOTECARD)-1;
        do {
            if(llGetInventoryName(INVENTORY_NOTECARD, i) == "Monogram")
            jump found_notecard;
        } while(--i>-1);
        llSay(DEBUG_CHANNEL, "Failed to find Monogram notecard.");
        return;
@found_notecard;
        i = 0;
        llGetNotecardLine("Monogram", i);
    }
    dataserver(key id, string data) {
        if(data == EOF) {
            llSetText("", <0,0,0>, .0);
            state monogram_menu;
        }
        if(data != "") monogram += data;
        integer percent = 100 * i/26;
        llSetText("Please wait, loading menu...\n" + wasProgress(percent, 10, ["[", "█", "░", "]"]) + "\n Memory: " + (string)llGetFreeMemory() + "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", wasPercentToGradient(percent, "rg"), 1);
        llGetNotecardLine("Monogram", ++i);
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}
 
state monogram_menu {
    state_entry() {
        wasMenuIndex = 0;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", wasDialogMenu(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], ["⏏ Exit", "⟻ Back", "Next ⟼"], ""), channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", wasDialogMenu(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], ["⏏ Exit", "⟻ Back", "Next ⟼"], ""), channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") {
            monogram = [];
            state options;
        }
        if(message == "⟻ Back") {
            llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", wasDialogMenu(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], ["⏏ Exit", "⟻ Back", "Next ⟼"], "<"), channel);
            return;
        }
        if(message == "Next ⟼") {
            llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", wasDialogMenu(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], ["⏏ Exit", "⟻ Back", "Next ⟼"], ">"), channel);
            return;
        }
        i = llGetListLength(monogram)-1;
        do {
            list m = llParseString2List(llList2String(monogram, i), ["="], []);
            if(message == llList2String(m, 0)) {
                llSetLinkPrimitiveParamsFast(9, [PRIM_TYPE, PRIM_TYPE_SCULPT, llList2String(m, 1), PRIM_SCULPT_TYPE_SPHERE]);
                llDialog(toucher, "\nWelcome to the Ampoule Bifocal Stereopticon.\nCreated in 2013 by Wizardry and Steamworks\n                 16 Nov 2013: Version: 1.0", wasDialogMenu(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], ["⏏ Exit", "⟻ Back", "Next ⟼"], ""), channel);
                return;
            }
        } while(--i>-1);
    }
    changed(integer change) {
        if(change & CHANGED_REGION)  llResetScript(); 
    }
    attach(key id) { ABS(id); }
}