// RICP : Robot Information/Control Protocol
//
// Vendor Sample for a no-config vendor object
//
// This kind of vendor puts prices into the object names,
// and associates images with products by some prefix/suffix.
//
// You can configure or modify the script to work with your
// vendors. This particular version works with nXC EzVendor V0.1
//
// Created: 2007-08-18
// Authors: Diva Canto and Felix Wakmann
//
// Copyright (c) 2007 by The Regents of the University of California.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

string gConfigFormatFile = "SLRCP config";

// the offset is used to pick a point in *front* of the vendor
vector gOffset = <0, -2, 0>;

// the prefix and suffix specify how an image name differs from the object name
string gPrefix = "pic_";
string gSuffix = "";

// number of digits of price on the end of the object (and image)
integer gPriceLen = 5;

// prints out location
integer gDebug = FALSE;


// ******** Internal Variables ********

// convert a floating point to an integer
string ftos(float n)
{
    return (string)((integer) (n + 0.5));
}

integer SLRCP_channel = 1020304;

// scan throught the objects and send them to the robot
startUpload(key target)
{
    string secret = (string)llFrand(1000000);
    list detailParts = llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_OWNER]);
    string owner = llList2String(detailParts, 0);
    string msg = "verify?tag=" + secret + "&owner=" + owner;
    // THis command sets the media URL *only* for the robot!
    // It does not affect other users
    llParcelMediaCommandList( [
        PARCEL_MEDIA_COMMAND_AGENT, (key)target,
        PARCEL_MEDIA_COMMAND_URL, msg
        ]);
    
    integer prefixLen = llStringLength(gPrefix);
    integer suffixLen = llStringLength(gSuffix);
    
    vector pos = llGetPos() + gOffset * llGetRot();
    string location = llGetRegionName() + "/" + ftos(pos.x) + "/" + ftos(pos.y) + "/" + ftos(pos.z);
    if (gDebug)
        llOwnerSay("secondlife://" + location);
    integer num = llGetInventoryNumber(INVENTORY_TEXTURE);
    while (num-- > 0)
    {
        string name = llGetInventoryName(INVENTORY_TEXTURE, num);
        if (startsWith(name, gPrefix) || endsWith(name, gSuffix))
        {
            string image = llGetInventoryKey(name);
            name = llGetSubString(name, prefixLen, -(suffixLen + 1));
            string id = llGetInventoryKey(name);
            string title = llGetSubString(name, 0, -(gPriceLen + 1));
            string price = llGetSubString(name, -gPriceLen, -1);
            
            integer i = 0;
            for (i = 0; llGetSubString(price, i, i) == "0"; i++)
                ;
            price = llGetSubString(price, i, 100);
            if (price == "")
                price = "0";
            publish(secret, target, id, title, "", image, location, price); 
        }
    }
}

integer startsWith(string str, string prefix)
{
    integer len =  llStringLength(prefix);
    if (len == 0)
        return TRUE;
    return llGetSubString(str, 0, len) == prefix;
}

integer endsWith(string str, string prefix)
{
    integer len =  llStringLength(prefix);
    if (len == 0)
        return TRUE;
    return llGetSubString(str, -len, 500) == prefix;
}

// publish info to the robot
publish(string tag, key target, string id, string title, string description, string image, string location, string price)
{
    string info = 
        "product?tag=" + tag +
            "&title=" + llEscapeURL(title) + 
            "&id=" + id +
            "&description=" + llEscapeURL(description) + 
            "&image=" + image + 
            "&location=" + llEscapeURL(location) + 
            "&price=" + llEscapeURL(price);
    llInstantMessage(target, info);
}


default
{
    // set up the listener
    state_entry()
    {
        llListen(SLRCP_channel, "", "", "");
    }
    
    // listen for a robot
    listen(integer chan, string name, key id, string msg)
    {
        // The incoming message msg looks like this:
        // robot|
        list parts = llParseStringKeepNulls(msg, ["|"], []);
        if (llList2String(parts, 0) == "robot") 
        {
            string bot = llList2String(parts, 1);
            if (bot == "")
                bot = id;
            
            startUpload(bot);
        }
    }
    
}