/*delegates are the win*/
function Delegate(f)
{
	this.func = f;
}
Delegate.prototype.func = function(){}
Delegate.create = function(obj, func)
{
	var f = function()
	{
		var target = arguments.callee.target;
		var func = arguments.callee.func;
		if(func && target)
		    return func.apply(target, arguments);
		return null;
	};

	f.target = obj;
	f.func = func;

	return f;
}

/*Delegate.prototype.createDelegate = function(obj)
{
	return create(obj, func);
}*/

String.prototype.toUSD = function() {
    var num = this.replace(/\$|\,/g, '');
    if (isNaN(num))
        num = "0";
    var sign = (num == (num = Math.abs(num)));
    num = Math.floor(num * 100 + 0.50000000001);
    var cents = num % 100;
    num = Math.floor(num / 100).toString();
    if (cents < 10)
        cents = "0" + cents;
    for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
        num = num.substring(0, num.length - (4 * i + 3)) + ',' +
    num.substring(num.length - (4 * i + 3));
    return (((sign) ? '' : '-') + '$' + num + '.' + cents);
}

String.prototype.isEmail = function() {
    var regex = new RegExp("^(([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5}){1,25})+([;.](([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\.([a-zA-Z]{2,5}){1,25})+)*$");
    return regex.test(this);
}

CanvasRenderingContext2D.prototype.drawCircle = function(centerX, centerY, radius, backgroundFill, strokeStyle, strokeWidth)
{
    this.beginPath();
    this.strokeStyle = strokeStyle;
    this.lineWidth = strokeWidth;
    this.fillStyle = backgroundFill;
    var full = 360*Math.PI/180;
    this.arc(centerX, centerY, radius, 0, full, false);
    this.fill();
    this.stroke();
    this.closePath();
}

var Treegloo = Class.create();

Treegloo.Calculator = Class.create({
    configurator: null,
    initialize: function(accentIds, subtotalFieldsArray, configurator){
        this.frameSelection = $('frame_selection');
        this.accentSelection = $('accent_selection');
        this.accentOption = $('options_accent');
        this.linerPrintOption = $('options_liner_prints');
        this.coverSelection = $('cover_selection');
        this.linerSelection = $('liner_selection');
        this.linerTypeSelection = $('liner_type_selection');
        this.latchOptionSelection = $('latch_option_selection');
        this.errorsContainer = $('error_container');
        this.subtotal = $('subtotal');
        if (accentIds == null)
            this.accentIds = new Array();
        else
            this.accentIds = accentIds;
        this.subtotalFieldsArray = subtotalFieldsArray;
        if (this.subtotalFieldsArray == null)
            this.subtotalFieldsArray = new Array();

        this.designCheckboxes = $$('.design_option_checkbox');
        this.deviceCheckboxes = $$('.device_option_checkbox');
        this.frameCheckboxes = $$('.frame_option_checkbox');

        //apply the observers
        for (var i = 0; i < this.designCheckboxes.length; i++)
            this.designCheckboxes[i].observe('click', Delegate.create(this, this.onDesignSelected));

        for (i = 0; i < this.deviceCheckboxes.length; i++) {
            this.deviceCheckboxes[i].observe('click', Delegate.create(this, this.onDeviceSelected));
            if (this.deviceCheckboxes[i].getAttribute('checked') != null)
                this.device = {id: this.deviceCheckboxes[i].getAttribute('device_id'), price: Number(this.deviceCheckboxes[i].getAttribute('device_id'))};
        }
        
        if (configurator) {
            if (configurator.canvas) {
                this.configurator = configurator;
            }
        }

        this.device = null;
        this.frame = null;
        this.accent = null;
        this.cover = null;
        this.liner = null;
        this.linerType = null;
        this.latchOption = null;
    },
    onDeviceSelected: function(e) {
        var element = Event.element(e);
        if (element) {
            var device_id = element.getAttribute('device_id');
            this.device = {id: device_id, price: Number(element.getAttribute('price'))};
            var frameLabels = $$('.frame_label');
            for (var  i = 0; i < this.frameCheckboxes.length; i++) {
                var frameCheckbox = this.frameCheckboxes[i];
                var framePrice = Number(frameCheckbox.getAttribute('price'));
                frameLabels[i].innerHTML = '$' + Number(framePrice + this.device.price);
            }

            for (var i = 0; i < this.designCheckboxes.length; i++) {
                var designBox = this.designCheckboxes[i];
                var designHolder = designBox.parentNode;
                var designBoxSiblings = designBox.adjacent(designBox.className);
                var devices = designBox.getAttribute('devices');
                var designType = designBox.getAttribute('design_type');
                var devicesArray = devices.split(',');
                var fieldToUpdate = null;
                var designOptionContainer = $('options_' + designType);

                if (devicesArray.indexOf(device_id) < 0)
                {
                    if (designBox.checked) {
                        designBox.checked = false;
                        switch(designType) {
                            case 'frame_finish':
                                fieldToUpdate = this.frameSelection;
                                if (this.configurator)
                                    this.configurator.frameObject = null;
                                break;
                            case 'cover_color':
                                fieldToUpdate = this.coverSelection;
                                if (this.configurator)
                                    this.configurator.coverObject = null;
                                break;
                            case 'liner_color':
                                fieldToUpdate = this.linerSelection;
                                if (this.configurator)
                                    this.configurator.linerObject = null;
                                break;
                            case 'liner_prints':
                                fieldToUpdate = this.linerSelection;
                                if (this.configurator)
                                    this.configurator.linerObject = null;
                                break;
                            case 'liner_type':
                                fieldToUpdate = this.linerTypeSelection;
                                if (this.configurator)
                                    this.configurator.linerType = null;
                                break;
                            case 'accent':
                                fieldToUpdate = this.accentSelection;
                                if (this.configurator)
                                    this.configurator.accentObject = null;
                                break;
                        }
                        if (fieldToUpdate)
                            fieldToUpdate.innerHTML = '';
                        this.configurator.update();
                    }
                    designHolder.style.display = "none";
                    var allHidden = true;
                    if (designBoxSiblings.length == 0)
                        allHidden = false;
                    for (var j = 0; j < designBoxSiblings.length; j++) {
                        if (designBoxSiblings[j].style.display != "none") {
                            allHidden = false;
                            break;
                        }
                    }
                    if (allHidden && designOptionContainer) {
                        designOptionContainer.style.display = "none";
                    }
                }
                else
                {
                    designHolder.style.display = "block";
                    if (designOptionContainer) {
                        if (designOptionContainer.style.display == "none" && designOptionContainer.getAttribute('enabled') != 'false') {
                            designOptionContainer.style.display = "block";
                        }
                    }
                }
            }
        }

        if (this.device)
            this.calculate();
    },
    onDesignSelected: function(e) {
        var element = Event.element(e);
        if (element)
        {
            var type = element.getAttribute('design_type');
            var designId = element.getAttribute('design_id');
            var designName = element.getAttribute('design_name');
            var imageUrl = element.getAttribute('image_url');
            var diagramImageUrl = element.getAttribute('diagram_image_url');
            var color = element.getAttribute('color');
            var price = element.getAttribute('price');
            var designTypePrice = element.getAttribute('design_type_price');
            var designTypeName = element.getAttribute('design_type_name');
            var design = {id: designId, name: designName, imageUrl: imageUrl, color: color, diagramImageUrl: diagramImageUrl, price: price, designTypePrice: designTypePrice, designTypeName: designTypeName};
            var fieldToUpdate = null;
            
            switch(type)
            {
                case 'frame_finish':
                    var isAccent = designName.indexOf('Accent') >= 0;
                    var isFabricWrapped = designName.indexOf('Wrapped') >= 0;
                    if (isAccent || isFabricWrapped) {
                        if (this.accentOption.style.display == "none") 
                        {
                            this.accentOption.setAttribute('enabled', 'true');
                            if (!Prototype.Browser.IE)
                                    this.accentOption.slideDown({duration: 0.5});
                            else
                                    this.accentOption.show();
                        }
                        if (isFabricWrapped)
                            $('design_type_name_accent').innerHTML = 'SUEDE';
                        else
                            $('design_type_name_accent').innerHTML = 'ACCENT';
                    }
                    else {
                        if (this.accentOption.style.display == '') 
                        {
                            this.accentOption.setAttribute('enabled', 'false');
                            if (!Prototype.Browser.IE)
                                    this.accentOption.slideUp({duration: 0.5});
                            else
                                    this.accentOption.hide();
                        }
                        this.accent = null
                        if (this.configurator)
                            this.configurator.accentObject = null;
                    }
                    fieldToUpdate = this.frameSelection;
                    this.frame = design;
                    
                    this.updateAccentImages();
                    if (this.accent != null)
                    {
                        if (isAccent)
                            designName = this.frame.name.replace('Accent', this.accent.name + ' Accent');
                        else
                            designName = this.frame.name.replace('Suede', this.accent.name);
                        if (this.accent != null)
                        {
                            //update the combo
                            if (isAccent)
                                imageUrl = '/images/design_combos/' + this.frame.id + '_' + this.accent.id + '.png';
                            else
                                imageUrl = '/images/designs/' + this.accent.id + '.png';
                        }
                        if (this.configurator)
                            this.configurator.accentObject = this.accent;
                    }
                    if (this.configurator)
                        this.configurator.frameObject = this.frame;
                    break;
                case 'cover_color':
                    fieldToUpdate = this.coverSelection;
                    this.cover = design;
                    if (this.configurator)
                        this.configurator.coverObject = this.cover;
                    break;
                case 'liner_color':
                    fieldToUpdate = this.linerSelection;
                    this.liner = design;
                    if (this.configurator)
                        this.configurator.linerObject = this.liner;
                    break;
                case 'liner_type':
                    this.linerType = design;
                    if (designName.indexOf('Cloth') >= 0 && this.linerPrintOption.style.display == '') {
                        this.linerPrintOption.setAttribute('enabled', 'false');
                        if (!Prototype.Browser.IE)
                            this.linerPrintOption.slideUp({duration: 0.5});
                        else
                            this.linerPrintOption.hide();

                        if (this.liner)
                            if (this.liner.designTypeName == "Liner Prints")
                            {
                                this.liner = null;
                                this.linerSelection.innerHTML = '';
                            }
                    }
                    else if (designName.indexOf('Cloth') == -1 && this.linerPrintOption.style.display == "none")
                    {
                        var children = this.linerPrintOption.select('.design_checkbox');
                        var childrenVisible = true;
                        for (var i = 0; i < children.length; i++) {
                            if (children[i].style.display == 'none') {
                                childrenVisible = false;
                                break;
                            }
                        }
                        if (childrenVisible) {
                            this.linerPrintOption.setAttribute('enabled', 'true');
                            if (!Prototype.Browser.IE)
                                this.linerPrintOption.slideDown({duration: 0.5});
                            else
                                this.linerPrintOption.show();
                        }
                    }
                    fieldToUpdate = this.linerTypeSelection;
                    break;
                case 'liner_prints':
                    fieldToUpdate = this.linerSelection;
                    this.liner = design;
                    if (this.configurator)
                        this.configurator.linerObject = this.liner;
                    break;
                case 'accent':
                    fieldToUpdate = this.frameSelection
                    this.accent = design;
                    var isAccent = this.frame.name.indexOf('Accent') >= 0;
                    var isFabricWrapped = this.frame.name.indexOf('Wrapped') >= 0;
                    if (isAccent)
                        designName = this.frame.name.replace('Accent', designName + ' Accent');
                    else
                        designName = this.frame.name.replace('Suede', designName);
                    //update the combo
                    if (isAccent)
                        imageUrl = '/images/design_combos/' + this.frame.id + '_' + this.accent.id + '.png';
                    else
                        imageUrl = '/images/designs/' + this.accent.id + '.png';
                    if (this.configurator)
                        this.configurator.accentObject = this.accent;
                    break;
                case 'latch_options':
                    fieldToUpdate = this.latchOptionSelection;
                    this.latchOption = design;
                    designName = this.latchOption.name;
                    $('latch_option_container').show();
                    break;
            }
            if (fieldToUpdate)
            {
                fieldToUpdate.innerHTML = '';
                if (imageUrl.length > 0)
                    fieldToUpdate.insert('<img src="' + imageUrl + '" width="20" height="20" align="top" />&nbsp;');
                fieldToUpdate.insert('<span>' + designName + '</span>');
            }
            if (this.configurator)
                this.configurator.update();
            this.calculate();
        }
    },
    validate: function() {
        if (this.errorsContainer) {
            this.errorsContainer.innerHTML = '<div class="info">Some quick notes:</div><div></div>';
            var pass = true;

            if (this.frame == null){
                this.errorsContainer.firstChild.insert('<div class="error" onclick="new Effect.ScrollTo(\'frame_finish_selector\', {duration: 0.3}); new Effect.Shake(\'frame_finish_selector\', {duration: 0.3, distance: 10, delay: 1});">The case needs a frame.</div>');
                new Effect.Shake('frame_finish_selector', {duration: 0.3, distance: 10});
                pass = false;
            }
            
            if (this.accent == null && (this.frame.name.indexOf('Accent') >= 0 || this.frame.name.indexOf('Suede Wrapped') >= 0)){
                this.errorsContainer.firstChild.insert('<div class="error" onclick="new Effect.ScrollTo(\'accent_selector\', {duration: 0.3}); new Effect.Shake(\'accent_selector\', {duration: 0.3, distance: 10, delay: 1});">This frame gets fabric liner.</div>');
                new Effect.Shake('accent_selector', {duration: 0.3, distance: 10});
                pass = false;
            }

            if (this.cover == null){
                this.errorsContainer.firstChild.insert('<div class="error" onclick="new Effect.ScrollTo(\'cover_color_selector\', {duration: 0.3}); new Effect.Shake(\'cover_color_selector\', {duration: 0.3, distance: 10, delay: 1});">A cover needs style, you know...</div>');
                new Effect.Shake('cover_color_selector', {duration: 0.3, distance: 10});
                pass = false;
            }

            if (this.liner == null){
                this.errorsContainer.firstChild.insert('<div class="error" onclick="new Effect.ScrollTo(\'liner_color_selector\', {duration: 0.3}); new Effect.Shake(\'liner_color_selector\', {duration: 0.3, distance: 10, delay: 1});">And inside the case?</div>');
                new Effect.Shake('liner_color_selector', {duration: 0.3, distance: 10});
                pass = false;
            }

            if (this.linerType == null){
                this.errorsContainer.firstChild.insert('<div class="error" onclick="new Effect.ScrollTo(\'liner_type_selector\', {duration: 0.3}); new Effect.Shake(\'liner_type_selector\', {duration: 0.3, distance: 10, delay: 1});">What type of liner do you want?</div>');
                new Effect.Shake('liner_type_selector', {duration: 0.3, distance: 10});
                pass = false;
            }

            if (!pass)
                this.errorsContainer.slideDown({duration: 0.8});
            else if (this.errorsContainer.style.display != 'none')
                this.errorsContainer.slideUp({duration: 0.3});
            return pass;
        }
        return true;
    },
    calculate: function() {
        var subTotal = 0;

        if (this.device)
            subTotal += Number(this.device.price);
        
        if (this.frame) {
            subTotal += Number(this.frame.price) + Number(this.frame.designTypePrice);
        }
        if (this.cover) {
            subTotal += Number(this.cover.price) + Number(this.cover.designTypePrice);
        }
        if (this.liner) {
            /*var freeLiner = false;
            if (this.frame == null)
                freeLiner = false;
            else if (Number(this.frame.price) > 50)
                freeLiner = true;
            if (!freeLiner)*/
                subTotal += Number(this.liner.price) + Number(this.liner.designTypePrice);
        }
        if (this.linerType) {
            subTotal += Number(this.linerType.price) + Number(this.linerType.designTypePrice);
        }
        
        if (this.latchOption) {
            subTotal += Number(this.latchOption.price) + Number(this.latchOption.designTypePrice);
        }
        
        this.subtotal.innerHTML = (subTotal > 0)?new String(subTotal).toUSD():"$0";
        for (var i = 0; i < this.subtotalFieldsArray.length; i++)
            $(this.subtotalFieldsArray[i]).value = (subTotal % 1 == 0)?subTotal + ".00":subTotal;
    },
    updateAccentImages: function() {
        if (this.frame) {
            var isAccent = this.frame.name.indexOf('Accent') >= 0;
            var isFabricWrapped = this.frame.name.indexOf('Wrapped') >= 0;
            for (var i = 0; i < this.accentIds.length; i++)
            {
                var accentImage = $('design_' + this.accentIds[i]);
                if (accentImage) {
                    if (isAccent)
                        accentImage.src = '/images/design_combos/' + this.frame.id + '_' + this.accentIds[i] + '.png';
                    else
                        accentImage.src = '/images/designs/' + this.accentIds[i] + '.png';
                }
            }
        }
    }
});

Treegloo.Configurator = Class.create({
    container: null,
    canvas: null,
    context: null,
    moveEffect: null,
    offset: {x: 0, y: 0},
    frameObject: null,
    linerObject: null,
    coverObject: null,
    accentObject: null,
    //defaultCoverColor: '#000000',
    //defaultLinerColor: '#60bb46',
    //defaultFrameColor: '#57b7df',
    defaultCoverColor: '#ffffff',
    defaultLinerColor: '#ffffff',
    defaultFrameColor: '#ffffff',
    linerImageElement: document.createElement('img'),
    linerPattern: null,
    currentLiner: null,
    frameImageElement: document.createElement('img'),
    framePattern: null,
    currentFrame: null,
    initialize: function(canvasContainerId, frameObject, linerObject, coverObject, accentObject) {
        this.container = $(canvasContainerId);
        this.canvas = document.createElement('canvas');
        this.canvas.id = 'configurator';
        this.canvas.width = '270';
        this.canvas.height = '200';
        this.canvas.style.position = 'absolute';
        this.canvas.style.top = Treegloo.Configurator.TOP_LIMIT + 'px';
        this.canvas.style.left = '-55px';
        //this.canvas.style.border = '1px solid red';

        this.container.insert(this.canvas);
        
        this.frameObject = frameObject;
        this.linerObject = linerObject;
        this.coverObject = coverObject;
        this.accentObject = accentObject;
        
        this.offset.x = -265;
        this.offset.y = -125;
        
        Event.observe(window, 'scroll', Delegate.create(this, this.onScroll));
        
        if (Prototype.Browser.IE) {
            try {
                G_vmlCanvasManager.initElement(this.canvas);
            }
            catch(err)
            {
                //unable to initialize excanvas;
            }
        }
        this.context = this.canvas.getContext('2d');
        this.update();
    },
    update: function() {
        //alert("IE = " + Prototype.Browser.IE);
        var xOffset = this.offset.x;
        var yOffset = this.offset.y;
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
        //console.log('w: ' + this.canvas.width + ', h: ' + this.canvas.height);
        var x = 0;//this.canvas.width;
        var y = 0;//this.canvas.height;
        var width = 25;
        var height = 25;
        if (this.coverObject != null)
        {
            this.drawCover(this.coverObject.color, {x:1+xOffset,y:126+yOffset});
        }
        else
            this.drawCover(this.defaultCoverColor, {x:1+xOffset,y:126+yOffset});

        if (this.linerObject) {
            if (this.linerObject.designTypeName == 'Liner Prints') {
                
                if (this.linerObject.diagramImageUrl != this.currentLiner) {
                    if (this.linerObject.diagramImageUrl != '') {
                        this.linerImageElement = document.createElement('img');
                        this.linerImageElement.src = this.linerObject.diagramImageUrl;
                        this.linerImageElement.observe('load', Delegate.create(this, this.onLinerImageLoad));
                    }
                    this.drawLiner(this.linerObject.color, {x:0+xOffset,y:128+yOffset});
                }
                else if (this.linerPattern != null) {
                    try {
                        this.drawLiner(this.linerPattern, {x:0+this.offset.x,y:128+this.offset.y});
                        //this.linerPattern = null;
                    }
                    catch(err) {
                        this.drawLiner(this.linerObject.color, {x:0+this.offset.x,y:128+this.offset.y});
                    }
                }
                else
                {
                    this.drawLiner(this.linerObject.color, {x:0+xOffset,y:128+yOffset});
                }
            }
            else
                this.drawLiner(this.linerObject.color, {x:0+xOffset,y:128+yOffset});
            this.currentLiner = this.linerObject.diagramImageUrl;
        }
        else
            this.drawLiner(this.defaultLinerColor, {x:0+xOffset,y:128+yOffset});

        if (this.frameObject) {
            if (this.accentObject) {
                if (this.frameObject.name.indexOf('Wrapped') >= 0)
                    this.drawFrame(this.accentObject.color, {x:-1+xOffset,y:200+yOffset});
                else if (this.frameObject.diagramImageUrl != this.currentFrame) {
                    if (this.frameObject.diagramImageUrl != '') {
                        this.frameImageElement = document.createElement('img');
                        this.frameImageElement.src = this.frameObject.diagramImageUrl;
                        this.frameImageElement.observe('load', Delegate.create(this, this.onFrameImageLoad));
                    }
                    this.drawFrame(this.frameObject.color, {x:-1+xOffset,y:200+yOffset});
                }
                else if (this.framePattern != null) {
                    try {
                        this.drawFrame(this.framePattern, {x:-1+xOffset,y:200+yOffset}, this.accentObject.color);
                        //this.linerPattern = null;
                    }
                    catch(err) {
                        this.drawFrame(this.frameObject.color, {x:-1+xOffset,y:200+yOffset}, this.accentObject.color);
                    }
                }
                else
                {
                    this.drawFrame(this.frameObject.color, {x:-1+xOffset,y:200+yOffset}, this.accentObject.color);
                }
            }
            else {
                if (this.frameObject.diagramImageUrl != this.currentFrame) {
                    if (this.frameObject.diagramImageUrl != '') {
                        this.frameImageElement = document.createElement('img');
                        this.frameImageElement.src = this.frameObject.diagramImageUrl;
                        this.frameImageElement.observe('load', Delegate.create(this, this.onFrameImageLoad));
                    }
                    this.drawFrame(this.frameObject.color, {x:-1+xOffset,y:200+yOffset});
                }
                else if (this.framePattern != null) {
                    try {
                        this.drawFrame(this.framePattern, {x:-1+xOffset,y:200+yOffset});
                        //this.linerPattern = null;
                    }
                    catch(err) {
                        this.drawFrame(this.frameObject.color, {x:-1+xOffset,y:200+yOffset});
                    }
                }
                else
                {
                    this.drawFrame(this.frameObject.color, {x:-1+xOffset,y:200+yOffset});
                }
            }
            this.currentFrame = this.frameObject.diagramImageUrl;
        }
        else
            this.drawFrame(this.defaultFrameColor, {x:-1+xOffset,y:200+yOffset}, '#ffffff');
    },
    drawFrame: function(fillStyle, offset, accentStyle) {
        this.context.strokeStyle = "#000000";
        this.context.lineWidth = .5;
        this.context.fillStyle = fillStyle;

        this.context.beginPath();
        this.drawObject(Treegloo.Configurator.Shapes.frameBase, offset);
        this.drawObject(Treegloo.Configurator.Shapes.frameHole, offset);
        this.context.closePath();

        this.context.fill();
        
        this.context.beginPath();
        this.drawObject(Treegloo.Configurator.Shapes.frameBase, offset);
        this.context.stroke();
        this.drawObject(Treegloo.Configurator.Shapes.frameHole, offset);
        this.context.stroke();
        this.context.closePath();

        //accent
        if (accentStyle) {
            this.context.fillStyle = accentStyle;
            this.context.beginPath();
            this.drawObject(Treegloo.Configurator.Shapes.accent, {x:offset.x, y:offset.y+5});
            this.context.closePath();
            this.context.fill();
        }
        
        this.context.beginPath();
        this.drawObject(Treegloo.Configurator.Shapes.frameLines, {x:offset.x, y:offset.y+5});
        this.context.closePath();
//        var altered = "";
//        var xFix = -1;
//        var yFix = -1;
//        for (var i = 0; i < Treegloo.Configurator.Shapes.accent.length; i++) {
//            var line = Treegloo.Configurator.Shapes.accent[i];
//            if (line.type == 'bezier')
//                altered += "{type: '"+line.type+"', cp1x: "+(Math.round((line.cp1x+xFix) * 100)/100)+", cp1y: "+(Math.round((line.cp1y+yFix) * 100)/100)+", cp2x: "+(Math.round((line.cp2x+xFix) * 100)/100)+", cp2y: "+(Math.round((line.cp2y+yFix) * 100)/100)+", x: "+(Math.round((line.x+xFix) * 100)/100)+", y: "+(Math.round((line.y+yFix) * 100)/100)+", stroke: "+((line.stroke)?true:false)+", reopen: "+((line.reopen)?true:false)+"},\n";
//            else
//                altered += "{type: '"+line.type+"', x: "+(Math.round((line.x+xFix) * 100)/100)+", y: "+(Math.round((line.y+yFix) * 100)/100)+", stroke: "+((line.stroke)?true:false)+", reopen: "+((line.reopen)?true:false)+"},\n";
//        }
//        console.log(altered);
        

        //this.context.fill();
    },
    drawLiner: function(fillStyle, offset) {
        this.context.strokeStyle = "#000000";
        this.context.lineWidth = .5;
        this.context.fillStyle = fillStyle;

        this.context.beginPath();
        this.drawObject(Treegloo.Configurator.Shapes.liner, offset);
        this.context.closePath();
        this.context.fill();
        this.context.stroke();

        this.context.beginPath();
        this.drawObject(Treegloo.Configurator.Shapes.linerLine1, offset);
        this.context.closePath();
        this.context.stroke();

        this.context.beginPath();
        this.drawObject(Treegloo.Configurator.Shapes.linerLine2, offset);
        this.context.closePath();
        this.context.stroke();

    },
    drawCover: function(fillStyle, offset) {
        this.context.strokeStyle = "#000000";
        this.context.lineWidth = .5;
        this.context.fillStyle = fillStyle;

        this.context.beginPath();
        this.drawObject(Treegloo.Configurator.Shapes.cover, offset);
        this.context.closePath();
        this.context.fill();
        this.context.stroke();
    },
    drawObject: function(object, offset) {
        for (var i = 0; i < object.length; i++)
        {
            var frame = object[i];
            switch(frame.type) {
                case 'bezier':
                    this.context.bezierCurveTo(
                        frame.cp1x+offset.x,
                        frame.cp1y+offset.y,
                        frame.cp2x+offset.x,
                        frame.cp2y+offset.y,
                        frame.x+offset.x,
                        frame.y+offset.y
                    );
                    break;
                case 'line':
                    this.context.lineTo(
                        frame.x+offset.x,
                        frame.y+offset.y
                    );
                    break;
                case 'move':
                    this.context.moveTo(
                        frame.x+offset.x,
                        frame.y+offset.y
                    );
                    break;
            }

            if (frame.mark == true) {
                this.context.closePath();
                this.context.stroke();
                this.context.drawCircle(frame.x+offset.x, frame.y+offset.y, 2, '#ff0000');
                this.context.beginPath();
            }

            if (frame.stroke == true) {
                this.context.stroke();
            }

            if (frame.reopen == true) {
                this.context.closePath();
                this.context.beginPath();
            }
        }
    },
    onLinerImageLoad: function(e) {
        try
        {
            this.linerPattern = this.context.createPattern(this.linerImageElement, 'repeat');
        }
        catch(err) {
            //console.log(err);
        }
        this.update();
    },
    onScroll: function(e) {
        if (this.moveEffect != null)
            this.moveEffect.cancel();        
        if (!Prototype.Browser.IE) {
            var moveTo = ((window.pageYOffset-50) > Treegloo.Configurator.TOP_LIMIT)?(window.pageYOffset-50):Treegloo.Configurator.TOP_LIMIT;
            this.moveEffect = new Effect.Morph(this.canvas, {style: 'top: '+moveTo+'px', duration: 1});
        }
        else {
            var moveTo = ((document.documentElement.scrollTop-50) > Treegloo.Configurator.TOP_LIMIT)?(document.documentElement.scrollTop-50):Treegloo.Configurator.TOP_LIMIT;
            this.moveEffect = new Effect.Move(this.canvas, {x: Number(this.canvas.style.left.replace('px', '')), y: moveTo, mode: 'absolute', duration: 1});
        }
            //this.moveEffect = new Effect.Morph(this.canvas, {style: 'top:'+moveTo+'px;', duration: 1});
    }
});
Treegloo.Configurator.TOP_LIMIT = 68;

//requires Delegate class
Treegloo.ImageSwitcher = Class.create({
    containerId: null,
    divImageClassName: 'switch_image',
    backgrounds: new Array(),
    tagLines: new Array(),
    tagLineWidths: new Array(),
    currentIndex: -1,
    currentImage: null,
    interval: 3,
    isActive: false,
    periodicalExecuter: null,
    initialize: function(containerId, divImageClassName, intervalInSeconds) {
        this.containerId = containerId;
        this.divImageClassName = divImageClassName;
        if (intervalInSeconds)
            this.interval = intervalInSeconds;
        this.capture();
    },
    capture: function() {
        this.backgrounds = $$('#'+this.containerId+' div.' + this.divImageClassName);
        for (var i = 0; i < this.backgrounds.length; i++) {
            this.backgrounds[i].style.zIndex = 100 - i;
            this.backgrounds[i].observe('click', Delegate.create(this, this.toggle));
            var children = this.backgrounds[i].childElements();
            for (var c = 0; c < children.length; c++) {
                if (children[c].hasClassName('tagline'))
                {
                    this.tagLines[i] = children[c];
                    this.tagLineWidths[i] = children[c].getWidth();
                    children[c].hide();
                    break;
                }
            }
        }
    },
    switchToDefault: function() {
        var random = Math.floor(Math.random()*(this.backgrounds.length-1));
        this.switchTo(random);
    },
    switchTo: function(imageIndex) {
        if (this.currentIndex == imageIndex && this.currentIndex != -1)
            return;
        if (this.currentIndex == -1)
            this.currentIndex = this.backgrounds.length-1;
        if (this.backgrounds.length == 0)
            this.capture();
        //place the next on top z-index
        this.currentImage = $(this.backgrounds[this.currentIndex]);
        var currentTagline = $(this.tagLines[this.currentIndex]);
        if (imageIndex >= this.backgrounds.length)
            this.currentIndex = 0;
        else
            this.currentIndex = imageIndex;
        var nextImage = this.backgrounds[this.currentIndex];
        var container = $(this.containerId);
        if (nextImage && this.currentImage && container)
        {
            if (this.currentEffect) {
				//this.currentImage.style.width = "100%";
            }
            //display:none
            /*for (var i = 0; i < this.backgrounds.length; i++)
                if (this.backgrounds[i] != nextImage)
                    this.backgrounds[i].style.zIndex = 100 - i;*/
            this.currentImage.style.zIndex = 100;
            nextImage.style.zIndex = 200;
            nextImage.style.width = "0%";
            nextImage.show();
            this.currentEffect = new Effect.Morph(nextImage, {style: 'width:100%;', afterFinish: Delegate.create(this, this.afterTransition)});

            if (currentTagline)
            {
                //currentTagline.style.zIndex = 60;
                currentTagline.slideUp({duration:0.8, afterFinish: Delegate.create(this, this.showCurrentTagline)});
            }
            else
            {
                this.showCurrentTagline();
            }
        }
    },
    switchNext: function() {
        /*if (this.currentEffect != null)
            return;*/
        if (this.backgrounds.length < 2)
            return;
        var nextIndex = this.currentIndex + 1;
        if (nextIndex >= this.backgrounds.length)
            nextIndex = 0;
        this.switchTo(nextIndex);
    },
    switchPrevious: function() {
        /*if (this.currentEffect != null)
            return;*/
        if (this.backgrounds.length < 2)
            return;
        var previousIndex = this.currentIndex - 1;
        if (previousIndex < 0)
            previousIndex = this.backgrounds.length-1;
        //console.log('switching to ' + this.currentIndex + '; ' + nextIndex + ' of ' + this.backgrounds.length);
        this.switchTo(previousIndex);
    },
    toggle: function() {
    	if (this.periodicalExecuter)
    		this.stop();
    	else
    		this.start();
    },
    start: function(intervalInSeconds, bypassSwitch)
    {
        if (this.backgrounds.length < 2)
            return;
        if (intervalInSeconds == null)
            intervalInSeconds = this.interval;
        this.stop();
        this.periodicalExecuter = new PeriodicalExecuter(Delegate.create(this, this.switchNext), intervalInSeconds);
        if (!bypassSwitch)
            this.switchNext();
    },
    stop: function()
    {
        if (this.periodicalExecuter)
        {
            this.periodicalExecuter.stop();
            this.periodicalExecuter = null;
        }
    },
    showCurrentTagline: function()
    {
        var nextTagline = this.tagLines[this.currentIndex];
        if (nextTagline)
        {
            //nextTagline.style.zIndex = 300;
            nextTagline.slideDown({duration:1.2, delay: 0.3});
        }
    },
    afterTransition: function () {
		this.currentImage.hide();
        for (var i = 0; i < this.backgrounds.length; i++) {
			this.backgrounds[i].style.width = "100%";
			if (this.backgrounds[i] != this.currentEffect.element)
				this.backgrounds[i].hide();
	    }
        this.currentEffect = null;
    }
});

Treegloo.DeviceSelector = Class.create({
    buttons: [],
    initialize: function(buttonsContainer, deviceDetailsContainer) {
        var actives = buttonsContainer.select('img.active');
        var inactives = buttonsContainer.select('img.inactive');
    } 
});

Treegloo.BackgroundImageObject = Class.create({
    url: "",
    projectId: 0,
    initialize: function(url, projectId){
        if (projectId)
            this.projectId = projectId;
        this.url = url;
    }
})

Treegloo.TagLineObject = Class.create({
    text: "",
    x: 0,
    y: 0,
    height: 0,
    width: 0,
    entersFrom: "",
    initialize: function(text, x, y, width, height, entersFrom){
        this.text = text;
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.entersFrom = entersFrom;
    }
})

//image must be loaded for this to work
Treegloo.PixelSelector = Class.create({
    image: null,
    xInfo: null,
    yInfo: null,
    colorInfo: null,
    swatchInfo: null,
    hexField: null,
    canvas: null,
    context: null,
    selectedColor: '#ffffffff',
    initialize: function(canvas, imageUrl, hexField, swatchInfo, xInfo, yInfo, colorInfo) {
        this.canvas = canvas;
        this.context = this.canvas.getContext('2d');
        this.hexField = hexField;

        this.xInfo = xInfo;
        this.yInfo = yInfo;
        this.colorInfo = colorInfo;
        this.swatchInfo = swatchInfo;

        this.image = document.createElement('img');
        this.image.src = imageUrl;
        this.image.observe('load', Delegate.create(this, this.onImageLoad));
        //document.appendChild(this.image);

        if (this.xInfo && this.yInfo && this.colorInfo)
            this.canvas.observe('mousemove', Delegate.create(this, this.updateInfo));
    },
    onImageLoad: function() {
        var data = this.context.drawImage(this.image, 0, 0);
        this.canvas.observe('click', Delegate.create(this, this.onCanvasClick));
    },
    onCanvasClick: function(e) {
        //console.log('at ' + x + ',' + y + ' = r:'+data[pixelIndex]+',g:'+data[pixelIndex+1]+',b:'+data[pixelIndex+2]+',a:'+data[pixelIndex+3]);
        this.selectedColor = this.updateInfo(e);
        if (this.hexField)
            this.hexField.value = this.selectedColor;
        if (this.swatchInfo)
            this.swatchInfo.style.backgroundColor = this.selectedColor;
    },
    updateInfo: function(e)
    {
        var element = Event.element(e);
        var offset = element.cumulativeOffset();
        var x = e.x-offset.left;
        var y = e.y-offset.top;
        var canvasWidth = this.canvas.getWidth();
        var canvasHeight = this.canvas.getHeight();
        var imageData = this.context.getImageData(0, 0, canvasWidth, canvasHeight);
        var data = imageData.data;
        var pixelIndex = (x + y * imageData.width) * 4;
        var colorHex = this.getHex(data[pixelIndex], data[pixelIndex+1], data[pixelIndex+2]);
        if (this.xInfo && this.yInfo && this.colorInfo)
        {
            this.xInfo.innerHTML = x;
            this.yInfo.innerHTML = y;
            this.colorInfo.innerHTML = '<div style="width: 100%; height:10px; background-color:'+colorHex+'">&nbsp;</div>r:&nbsp;'+data[pixelIndex]+'<br />g:&nbsp;'+data[pixelIndex+1]+'<br />b:&nbsp;'+data[pixelIndex+2]+'<br />a:&nbsp;'+data[pixelIndex+3];
        }
        return colorHex;
    },
    getHex: function(red, green, blue) {
        var hexString = "#";
        for (var i = 0; i < arguments.length; i++) {
            if (arguments[i] == null)
                hexString += "00";
            else {
                var n = parseInt(arguments[i]);
                if (n == 0 || isNaN(n)) 
                    hexString += "00";
                n = Math.max(0, n);
                n = Math.min(255, n);
                n = Math.round(n);
                hexString += "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16);
            }   
        }
        return hexString;
    }
})

