

function TwoStateImage () {
    this.element = null;
    
    this.selected = false;
    
    this.currentState = false;
    
    this.state = {
        normal : {
            on : null,
            off : null
        },
        selected : {
            on : null,
            off : null
        }
    };
    
    this.sourceType = TwoStateImage.SOURCE_TYPE_IMAGE;
    
    this.suffix = {
        normal : {
            on : TwoStateImage.SUFFIX_NORMAL_ON,
            off : TwoStateImage.SUFFIX_NORMAL_OFF
        },
        selected : {
            on : TwoStateImage.SUFFIX_SELECTED_ON,
            off : TwoStateImage.SUFFIX_SELECTED_OFF
        }
    };
    
    this.twoStateImageListeners = new Array();
    
}

TwoStateImage.IMAGE_NORMAL_OFF = 0;
TwoStateImage.IMAGE_NORMAL_ON = 1;
TwoStateImage.IMAGE_SELECTED_OFF = 2;
TwoStateImage.IMAGE_SELECTED_ON = 3;

TwoStateImage.MODE_ALL_DEFINED = 'all-defined';
TwoStateImage.MODE_GENERATE_URL = 'generate-url';

TwoStateImage.SOURCE_TYPE_IMAGE = 0;
TwoStateImage.SOURCE_TYPE_BACKGROUND = 1;


TwoStateImage.SUFFIX_NORMAL_OFF = 'a';
TwoStateImage.SUFFIX_NORMAL_ON = 'b';
TwoStateImage.SUFFIX_SELECTED_OFF = 'c';
TwoStateImage.SUFFIX_SELECTED_ON = 'd';


TwoStateImage.subscribes = function (element) {
    var target = element;
    var options = {
            mode : TwoStateImage.MODE_GENERATE_URL,
            url : null,
            part : 4,
            source : TwoStateImage.SOURCE_TYPE_IMAGE
        };
    var selected = false;
    var currentState = false;
    var onCreateFunction = null;
    
    
    switch (arguments.length) {
        case 5 : {
            onCreateFunction = arguments[4];
            
        }
        
        case 4 : {
            currentState = (arguments[3] != null) ? arguments[3] : currentState;
            
            currentState = (currentState === true) ? true : false;
            
        }
        
        case 3 : {
            selected = (arguments[2] != null) ? arguments[2] : selected;
            
            selected = (selected === true) ? true : false; 
            
        };
        
        case 2 : {
            options = (arguments[1] != null) ? arguments[1] : options;
            
        } break;
        
        
        default : {
            // do nothing
        } break;
        
    }
    
    
    if ((!options.mode)
            || ((options.mode != TwoStateImage.MODE_ALL_DEFINED)
                && (options.mode != TwoStateImage.MODE_GENERATE_URL))) {
        options.mode = TwoStateImage.MODE_GENERATE_URL;
        options.part = 4;
    }
    
    if (!options.url) {
        options.url = null;
    }
    
    if ((!options.source)
            || ((options.source != TwoStateImage.SOURCE_TYPE_IMAGE)
                && (options.source != TwoStateImage.SOURCE_TYPE_BACKGROUND))) {
        options.source = TwoStateImage.SOURCE_TYPE_IMAGE;
    }
    
    window.appendLoadEvent(function () {
        if (typeof element == 'string') {
            target = document.getElementById(element);
            if (DomTools.isElement(target) == false) {
                return false;
            }
        }
        
        
        var tsi = new TwoStateImage();
        tsi.setElement(target);
        
        
        if (options.mode == TwoStateImage.MODE_GENERATE_URL) {
            tsi.setImage(options.url, options.part);
            
        } else {
            if (options.normal) {
                if (options.normal.on) {
                    tsi.setOnImage(options.normal.on);
                }
                
                if (options.normal.off) {
                    tsi.setOffImage(options.normal.off);
                }
                
            }
            
            if (options.selected) {
                if (options.selected.on) {
                    tsi.setSelectedOnImage(options.selected.on);
                }
                
                if (options.selected.off) {
                    tsi.setSelectedOffImage(options.selected.off);
                }
                
            }
            
            
            
        }
        
        if (onCreateFunction != null) {
            return onCreateFunction(tsi);
        }
        
        return true;
    });
    
    return true;
}

TwoStateImage.prototype.setElement = function (node) {
    DomTools.addHelpers(node);
    
    node.rugama.set('TwoStateImage', this);
    
    this.element = node;
    
    if (this.element.nodeName.toLowerCase() == 'img') {
        this.sourceType = TwoStateImage.SOURCE_TYPE_IMAGE;
        
    } else {
        this.sourceType = TwoStateImage.SOURCE_TYPE_BACKGROUND;
        
    }
    
}

TwoStateImage.prototype.associatesWithRollover = function () {
    var self = this;
    
    
    this.element.appendNewEvent('mouseover',
        function () {
            self.toggle();
            return true;
        })
    
    this.element.appendNewEvent('mouseout',
        function () {
            self.toggle();
            return true;
        })
}

TwoStateImage.prototype.associatesWithClick = function () {
    var self = this;
    
    this.element.appendNewEvent('click',
        function () {
            self.changeState();
            return true;
        })
    
}


TwoStateImage.prototype.appendTwoStateImageListener = function (twoStateImageEvent) {
    rolloverEvent.owner = this;
    
    if (!twoStateImageEvent.off) {
        twoStateImageEvent.off = function () {
            return true;
        }
    }
    
    if (!twoStateImageEvent.on) {
        twoStateImageEvent.on = function () {
            return true;
        }
    }
    
    if (!twoStateImageEvent.toggle) {
        twoStateImageEvent.toggle = function () {
            return true;
        }
    }
    
    if (!twoStateImageEvent.select) {
        twoStateImageEvent.select = function () {
            return true;
        }
    }
    
    if (!twoStateImageEvent.unselect) {
        twoStateImageEvent.unselect = function () {
            return true;
        }
    }
    
    if (!twoStateImageEvent.changeState) {
        twoStateImageEvent.changeState = function () {
            return true;
        }
    }
    
    this.twoStateImageListeners.push(rolloverEvent);
    
}

TwoStateImage.prototype.removeTwoStateImageListener = function (rolloverEvent) {
    var i = 0;
    var sz = this.twoStateImageListeners.length;
    
    for (i = 0; i < sz; i++) {
        if (this.twoStateImageListeners[i] != rolloverEvent) {
            continue;
        }
        
        this.twoStateImageListeners[i].owner = null;
        delete this.twoStateImageListeners[i];
    }
    
}


TwoStateImage.prototype.setImage = function (url, part) {
    if (url == null) {
        if (!this.element) {
            return false;
        }
        
        if (this.sourceType == TwoStateImage.SOURCE_TYPE_IMAGE) {
            if (!this.element.src) {
                return false;
            }
            
            url = this.element.src;
            
        } else if (this.sourceType == TwoStateImage.SOURCE_TYPE_BACKGROUND) {
            url = this.element.getActualStyle('background-image');
            if ((url.length < 1)
                    || (url == 'undefined')) {
                url = new String(this.element.getActualStyle('backgroundImage'));
                
            }
            
        }
        
        if ((url.length < 1)
                || (url == 'undefined')) {
            return false;
        }
        
        url = url.unQuote('url(', ')');
        url = url.unQuote();
        
    }
    
    switch (part) {
        case 2 : {
            this.set2Images(url);
            
        } break;
        
        case 3 : {
            this.set3Images(url);
            
        } break;
        
        case 4 : {
            this.set4Images(url);
            
        } break;
        
        default : {
            this.setOffImage(url);
            this.setOnImage(url);
            this.setSelectedOffImage(url);
            this.setSelectedOnImage(url);
            
        } break;
        
    }
    
    return true;
}


TwoStateImage.prototype.set2Images = function (url) {
    var fi = (new String(url)).getPathInfo();
    
    if (fi === null) {
        return;
    }
    
    this.setOffImage(url);
    this.setOnImage(fi.changeSuffix(TwoStateImage.SUFFIX_NORMAL_ON));
    this.setSelectedOffImage(fi.changeSuffix(TwoStateImage.SUFFIX_NORMAL_OFF));
    this.setSelectedOnImage(fi.changeSuffix(TwoStateImage.SUFFIX_NORMAL_ON));
}

TwoStateImage.prototype.set3Images = function (url) {
    var fi = (new String(url)).getPathInfo();
    
    if (fi === null) {
        return;
    }
    
    this.setOffImage(url);
    this.setOnImage(fi.changeSuffix(TwoStateImage.SUFFIX_NORMAL_ON));
    this.setSelectedOffImage(fi.changeSuffix(TwoStateImage.SUFFIX_SELECTED_OFF));
    this.setSelectedOnImage(fi.changeSuffix(TwoStateImage.SUFFIX_SELECTED_OFF));
    
}

TwoStateImage.prototype.set4Images = function (url) {
    var fi = (new String(url)).getPathInfo();
    
    if (fi === null) {
        return;
    }
    
    this.setOffImage(url);
    this.setOnImage(fi.changeSuffix(TwoStateImage.SUFFIX_NORMAL_ON));
    this.setSelectedOffImage(fi.changeSuffix(TwoStateImage.SUFFIX_SELECTED_OFF));
    this.setSelectedOnImage(fi.changeSuffix(TwoStateImage.SUFFIX_SELECTED_ON));
    
}

TwoStateImage.prototype.setOffImage = function (url) {
    var img = new Image();
    img.src = url;
    this.state.normal.off = img.src;
}

TwoStateImage.prototype.setOnImage = function (url) {
    var img = new Image();
    img.src = url;
    this.state.normal.on = img.src;
}

TwoStateImage.prototype.setSelectedOffImage = function (url) {
    var img = new Image();
    img.src = url;
    this.state.selected.off = img.src;
}

TwoStateImage.prototype.setSelectedOnImage = function (url) {
    var img = new Image();
    img.src = url;
    this.state.selected.on = img.src;
}

TwoStateImage.prototype.on = function () {
    if (this.element == null) {
        return true;
    }
    
    var i = 0;
    var sz = this.twoStateImageListeners.length;
    for (i = 0; i < sz; i++) {
        if (this.twoStateImageListeners[i].on() === false) {
            return true;
        }
    }
    
    
    if (this.selected == true) {
        if (this.sourceType == TwoStateImage.SOURCE_TYPE_IMAGE) {
            this.element.src = this.state.selected.on;
            
        } else if (this.sourceType == TwoStateImage.SOURCE_TYPE_BACKGROUND) {
            this.element.style.backgroundImage = 'url(' + this.state.selected.on + ')';
            
        }
        
    } else {
        if (this.sourceType == TwoStateImage.SOURCE_TYPE_IMAGE) {
            this.element.src = this.state.normal.on;
            
        } else if (this.sourceType == TwoStateImage.SOURCE_TYPE_BACKGROUND) {
            this.element.style.backgroundImage = 'url(' + this.state.normal.on + ')';
            
        }
    }
    
    this.currentState = true;
    return true;
}

TwoStateImage.prototype.off = function () {
    if (this.element == null) {
        return true;
    }
    
    var i = 0;
    var sz = this.twoStateImageListeners.length;
    for (i = 0; i < sz; i++) {
        if (this.twoStateImageListeners[i].off() === false) {
            return true;
        }
    }
    
    if (this.selected == true) {
        if (this.sourceType == TwoStateImage.SOURCE_TYPE_IMAGE) {
            this.element.src = this.state.selected.off;
            
        } else if (this.sourceType == TwoStateImage.SOURCE_TYPE_BACKGROUND) {
            this.element.style.backgroundImage = 'url(' + this.state.selected.off + ')';
            
        }
        
    } else {
        if (this.sourceType == TwoStateImage.SOURCE_TYPE_IMAGE) {
            this.element.src = this.state.normal.off;
            
        } else if (this.sourceType == TwoStateImage.SOURCE_TYPE_BACKGROUND) {
            this.element.style.backgroundImage = 'url(' + this.state.normal.off + ')';
            
        }
        
        
    }
    
    this.currentState = false;
    return true;
}



TwoStateImage.prototype.toggle = function () {
    if (this.element == null) {
        return true;
    }
    
    var i = 0;
    var sz = this.twoStateImageListeners.length;
    for (i = 0; i < sz; i++) {
        if (this.twoStateImageListeners[i].toggle() === false) {
            return true;
        }
    }
    
    if (this.currentState == true) {
        this.off();
        
    } else {
        this.on();
        
    }
    
    return true;
}

TwoStateImage.prototype.unselect = function () {
    if (this.element == null) {
        return true;
    }
    
    var i = 0;
    var sz = this.twoStateImageListeners.length;
    for (i = 0; i < sz; i++) {
        if (this.twoStateImageListeners[i].unselect() === false) {
            return true;
        }
    }
    
    this.selected = false;
    
    this.toggle();
    
    return true;
}

TwoStateImage.prototype.select = function () {
    if (this.element == null) {
        return true;
    }
    
    var i = 0;
    var sz = this.twoStateImageListeners.length;
    for (i = 0; i < sz; i++) {
        if (this.twoStateImageListeners[i].select() === false) {
            return true;
        }
    }
    
    this.selected = true;
    
    this.toggle();
    
    return true;
}

TwoStateImage.prototype.changeState = function () {
    if (this.element == null) {
        return true;
    }
    
    var i = 0;
    var sz = this.twoStateImageListeners.length;
    for (i = 0; i < sz; i++) {
        if (this.twoStateImageListeners[i].changeState() === false) {
            return true;
        }
    }
    
    if (this.selected == true) {
        this.unselect();
        
    } else {
        this.select();
        
    }
    
    return true;
}


