
if (typeof(SimpleColorPalette) == 'undefined') {
    SimpleColorPalette = function() {
        this.initialize.apply(this, arguments);
    }
}

update(SimpleColorPalette, {
    palettes: [],
    append: function(elements) {
        var self = this;
        forEach(elements, function(element) {
            self.palettes.push(new SimpleColorPalette(element));
        });
    },

    createPalette: function() {
        if (!this._colorPalette) {
            var pal = this.palette();
            var gen_row = compose(partial(TR, null), partial(map, bind(this.createPaletteTD, this)));
            this._colorPalette = DIV(
                null, TABLE({style: 'width:auto;border: 1px solid #333;border-spacing:1px;margin:0px; padding:0px;'}, TBODY({style: 'width:auto'}, map(gen_row, pal)))
            );
        }
        return this._colorPalette.cloneNode(true);
    },

    createPaletteTD: function(col) {
        if (!this._td) {
            this._td = TD();
            with(this._td.style) {
                width = 'auto';
                height = '10px';
                cursor = 'pointer';
            }
        }
        var td = this._td.cloneNode(false);
        td.style.backgroundColor = col;
        td.title = col;
        return td;
    },

    allPalettesHide: function() {
        forEach(this.palettes, methodcaller('colorPaletteHide'));
    },

    palette: function() {
        if (!this._palette) {
           var palette = [];
           var clist = ['00', '33', '66', '99', 'CC', 'FF'];
           var flag = true;

           var clToggle = function() {
             if (flag) {
                 flag = false;
                 return clist;
             } else {
                 flag = true;
                 return clist.concat().reverse();
             }
           }
           var cl = []
           forEach(clist, function(c1) {
              forEach(clist, function(c2) {
                forEach(clToggle(), function(c3) {
                    cl.push('#' + c1 + c2 + c3);
                    if(cl.length == 36) {
                        var co = clist[palette.length];
                        cl.unshift('#' + co + co + co);
                        palette.push(cl);
                        cl = [];
                    }
                });
              });
           });
           this._palette = palette;
        }
        return this._palette;
    }
});
bindMethods(SimpleColorPalette.PALETTE);

SimpleColorPalette.prototype = {
    initialize: function(element) {
        this.input = element;
        this.createColorView();
        connect(this.input, 'onkeyup', this, this.changeColorListener);
    },

    COLOR_VIEW_SIZE: [20, 20],
    createColorView: function() {
        this.colorView = SPAN();
        this.colorView.innerHTML = '&nbsp;&nbsp;&nbsp;'
        with(this.colorView.style) {
            width = this.COLOR_VIEW_SIZE[0] + 'px';
            height = this.COLOR_VIEW_SIZE[1] + 'px';
            backgroundColor = '#ffffff';
            cursor = 'pointer';
            border = '1px solid #999999';
            verticalAlign = 'middle';
        }
        this.input.parentNode.insertBefore(this.colorView, this.input.nextSibling);
        this.changeColorListener();
        this.identLoadPalette = connect(this.colorView, 'onclick', this, this.createColorPalette)
    },

    toggleColorList: function() {
        var clist = ['00', '33', '66', '99', 'CC', 'FF'];
        return function() {
          if (flag) {
              flag = false;
              return clone(clist);
          } else {
              flag = true;
              return clone(clist).reverse();
          }
        }
    },
    createColorPalette: function() {
        disconnect(this.identLoadPalette);
        this.colorPalette = SimpleColorPalette.createPalette();
        with(this.colorPalette.style) {
            backgroundColor = '#ffffff';
            position = 'absolute';
        }

        connect(this.colorPalette, 'onclick', this, function(ev) {
            var td = ev.target();
            if (td.nodeName == 'TD') {
                this.changeColor(td.title);
                this.colorPaletteHide();
            }
        });
        connect(this.colorPalette, 'onmouseover', this, function(ev) {
            var td = ev.target();
            if (td.nodeName == 'TD') {
                this.colorView.style.backgroundColor = td.title;
            }
        });
        connect(this.colorPalette, 'onmouseout', this, this.changeColorListener);

        this.colorView.parentNode.insertBefore(this.colorPalette, this.colorView.nextSibling);
        this.paletteMove();
        SimpleColorPalette.allPalettesHide();
        this.colorPaletteVisiable();

        connect(this.colorView, 'onclick', this, this.colorPaletteToggle);
    },

    changeColor: function(col) {
        this.input.value = col;
        this.changeColorListener();
    },

    colorPaletteToggle: function() {
        with(this.colorPalette.style) {
            if (display != 'none') {
                display = 'none';
            } else {
                this.paletteMove();
                SimpleColorPalette.allPalettesHide();
                display = 'block';
            }
        }
    },

    colorPaletteVisiable: function() {
        if (this.colorPalette)
            this.colorPalette.style.display = 'block';
    },

    colorPaletteHide: function() {
        if (this.colorPalette)
            this.colorPalette.style.display = 'none';
    },

    paletteMove: function() {
        //if( false ) {
        if( !window.opera ) {
            var pos = getElementPosition(this.colorView);
            if( getViewportDimensions().w - pos.x < 300 ) {
                pos.x = getViewportDimensions().w - 300 + this.COLOR_VIEW_SIZE[0];
            }
            pos.x = Math.max(pos.x + this.COLOR_VIEW_SIZE[0], 0);
            // pos.y += 25;
            setElementPosition(this.colorPalette, pos);
        }
    },

    COLOR_REGEXP: new RegExp('^#[0-9a-f-A-f]{6}$'),
    changeColorListener: function() {
        var color = this.input.value;
        if (this.COLOR_REGEXP.test(color)) {
            this.colorView.style.backgroundColor = color;
        } else {
            this.colorView.style.backgroundColor = '#ffffff';
        }
    }
};

