//
// Counter
//
var Counter = Control.subclass({
    className: "Counter",
    content: [
        " You’ve clicked this ",
        {
            html: "<span>0</span>",
            id: "count"
        },
        " times. "
    ]
});
Counter.prototype.extend({
    initialize: function() {
        // Points to above span.
        var $count = this.$count();
        this.click( function( event ) {
            $count.text(1 + parseInt( $count.text() ) );
        });
        
        // Extra measures to disable text selection on double-click
        if ( $.browser.msie ) {
            this.bind( "selectstart", function() { return false; } );
        } else if ( !$.browser.mozilla ) {
            this.mousedown( function() { return false; } );
        }
    }
});

//
// Counters
//
var Counters = Control.subclass({
    className: "Counters",
    content: [
        " ",
        {
            control: "Counter"
        },
        " ",
        {
            control: "Counter"
        },
        " ",
        {
            control: "Counter"
        },
        " "
    ]
});

//
// Ellipsis
//
var Ellipsis = Control.subclass({
    className: "Ellipsis",
    content: "…"
});

//
// Feature
//
var Feature = Control.subclass({
    className: "Feature",
    content: [
        " ",
        {
            html: "<div class=\"table\" />",
            content: [
                " ",
                {
                    html: "<div class=\"row\" />",
                    content: [
                        " ",
                        {
                            html: "<div class=\"cell\" />",
                            content: [
                                " ",
                                {
                                    html: "<h2 />",
                                    id: "Feature_name"
                                },
                                " ",
                                {
                                    control: "SourceCode",
                                    id: "Feature_markup"
                                },
                                " "
                            ]
                        },
                        " ",
                        {
                            html: "<div class=\"cell\" />",
                            content: [
                                " ",
                                {
                                    html: "<div />",
                                    id: "Feature_content"
                                },
                                " ",
                                "<div class=\"label\">Sample usage</div>",
                                " ",
                                {
                                    control: "SourceCode",
                                    id: "Feature_example"
                                },
                                " ",
                                "<div class=\"label separator\">Live demo</div>",
                                " ",
                                {
                                    html: "<div />",
                                    id: "Feature_result"
                                },
                                " "
                            ]
                        },
                        " "
                    ]
                },
                " "
            ]
        },
        " "
    ]
});
Feature.prototype.extend({
    content: Control.chain( "$Feature_content", "content" ),
    demoClass: Control.chain( "$Feature_result", "transmute" ),
    example: Control.chain( "$Feature_example", "content" ),
    markup: Control.chain( "$Feature_markup", "content" ),
    name: Control.chain( "$Feature_name", "content" )
});

//
// FeatureBrowserIsolationDemo
//
var FeatureBrowserIsolationDemo = Control.subclass({
    className: "FeatureBrowserIsolationDemo",
    content: [
        " ",
        {
            control: "Gradient",
            start: "#808080",
            end: "#f0f0f0"
        },
        " "
    ]
});

//
// FeatureElementIDs
//
var FeatureElementIDs = Feature.subclass({
    className: "FeatureElementIDs",
    demoClass: "Counters",
    name: "Refer to DOM elements as class members",
    content: "   <source>\n<pre>\n&lt;Control name=\"Counter\"&gt;\n\n&lt;content&gt;\nYou’ve clicked this\n&lt;span id=\"count\"&gt;0&lt;/span&gt;\ntimes.\n&lt;/content&gt;\n\n&lt;script&gt;\nCounter.prototype.extend({\ninitialize: function() {\n  // Points to above span.\n  var $count = this.$count();\n  this.click(function() {\n    $count.text(1 +\n     parseInt($count.text()));\n  });\n}\n});\n&lt;/script&gt;\n\n&lt;/Control&gt;\n</pre>\n</source>  ",
    example: " <pre>\n&lt;Counter/&gt;\n&lt;Counter/&gt;\n&lt;Counter/&gt;\n</pre> "
});

//
// FeatureHtmlMacrosDemo
//
var FeatureHtmlMacrosDemo = Control.subclass({
    className: "FeatureHtmlMacrosDemo",
    content: [
        " ",
        {
            control: "Greet2"
        },
        " Yes! ",
        {
            control: "Greet2"
        },
        " "
    ]
});

//
// FeatureMarkupAndCSSDemo
//
var FeatureMarkupAndCSSDemo = Control.subclass({
    className: "FeatureMarkupAndCSSDemo",
    content: [
        " Quick markup has ",
        {
            control: "Tag",
            content: "style"
        },
        " and ",
        {
            control: "Tag",
            content: "script"
        },
        " elements, just like HTML. "
    ]
});

//
// FeaturePropertiesDemo
//
var FeaturePropertiesDemo = Control.subclass({
    className: "FeaturePropertiesDemo",
    content: [
        " ",
        {
            control: "Recipe",
            name: "Lasagna",
            rating: "3",
            content: " Quick and easy lasagna "
        },
        " ",
        {
            control: "Recipe",
            name: " Pasta <i>con i fagioli</i> ",
            rating: "5",
            content: " A <b>great</b> Tuscan peasant dish "
        },
        " "
    ]
});

//
// FeatureScopingDemo
//
var FeatureScopingDemo = Control.subclass({
    className: "FeatureScopingDemo",
    content: [
        " ",
        {
            control: "Red"
        },
        " ",
        {
            control: "Green"
        },
        " "
    ]
});

//
// FeatureSubclassingDemo
//
var FeatureSubclassingDemo = Control.subclass({
    className: "FeatureSubclassingDemo",
    content: [
        " ",
        {
            control: "OrangeButton",
            id: "buttonShow",
            content: "Show dialog"
        },
        " "
    ]
});
FeatureSubclassingDemo.prototype.extend({
    initialize: function() {
        this.$buttonShow().click(function() {
            Dialog.showDialog(SampleDialog);
        });
    }
});

//
// GetStartedModule
//
var GetStartedModule = Control.subclass({
    className: "GetStartedModule",
    content: [
        " ",
        "<h2>Get started</h2>",
        " ",
        {
            html: "<ul />",
            content: [
                " ",
                {
                    html: "<li />",
                    content: [
                        {
                            control: "Link",
                            href: "/downloads",
                            content: "Download QuickUI"
                        }
                    ]
                },
                " ",
                {
                    html: "<li />",
                    content: [
                        {
                            control: "Link",
                            href: "/markup/tutorial",
                            content: "Read the Tutorial"
                        }
                    ]
                },
                " "
            ]
        },
        " "
    ]
});

//
// Gradient
//
var Gradient = Control.subclass({
    className: "Gradient"
});
Gradient.prototype.extend({
    
    initialize: function() {
        this._redraw();
    },
    
    end: Control.property(function() { this._redraw(); }),
    direction: Control.property(function() { this._redraw(); }, "vertical"),
    start: Control.property(function() { this._redraw(); }),
    
    _redraw: function() {
        var direction = this.direction();
        var start = this.start();
        var end = this.end();
        if (direction && start && end)
        {
            var horizontal = (direction == "horizontal");
            var startColorString = this._hexColorToRgbString(start);
            var endColorString = this._hexColorToRgbString(end);
            var property;
            var value;
            if ($.browser.mozilla)
            {
                property = "background-image";
                var position = horizontal ? "left" : "top";
                value = "-moz-linear-gradient(" + position + ", " + startColorString + ", " + endColorString + ")";
            }
            else if ($.browser.webkit)
            {
                property = "background-image"; 
                var position2 = horizontal ? "right top" : "left bottom";
                value = "-webkit-gradient(linear, left top, " + position2 + ", from(" + startColorString + "), to(" + endColorString + "))";
            }
            else if ($.browser.msie)
            {
                property = "filter";
                var gradientType = horizontal ? 1 : 0;
                value = "progid:DXImageTransform.Microsoft.gradient(gradientType=" + gradientType + ", startColorStr=" + start + ", endColorStr=" + end + ")"; 
            }

            this.css(property, value);
        }
    },
    
    /* Convert a hex color like #00ff00 to "rgb(0, 255, 0)" */
    _hexColorToRgbString: function(hex) {
        if (hex.substr(0, 1) == "#")
        {
            // Remove "#"
            hex = hex.substring(1);
        }
        var hasAlpha = (hex.length == 8);
        var color = parseInt(hex, 16);
        var colorStringType = hasAlpha ? "rgba" : "rgb";
        
        var alphaString = "";
        if (hasAlpha)
        {
            // Alpha
            a = color & 0xFF;
            alphaString = "," + a;
            color = color >> 8;
        }
        
        var r = (color >> 16) & 0xFF;
        var g = (color >> 8)  & 0xFF;
        var b = color         & 0xFF;
        
        var rgbString = colorStringType + "(" + r + "," + g + "," + b + alphaString + ")";
        return rgbString;
    }
    
});

//
// Green
//
var Green = Control.subclass({
    className: "Green",
    content: " <div class=\"message\">I’m green</div> "
});

//
// Greet
//
var Greet = Control.subclass({
    className: "Greet",
    content: " Hello, world! "
});

//
// Greet2
//
var Greet2 = Control.subclass({
    className: "Greet2",
    content: " Hello <i>world!</i> "
});

//
// HomePage
//
var HomePage = SitePage.subclass({
    className: "HomePage",
    area: "Home",
    title: "QuickUI web control framework",
    sidebar: [
        " ",
        {
            control: "GetStartedModule"
        },
        " "
    ],
    content: [
        " ",
        " ",
        "<p>\nQuickUI (Quick User Interface) is a framework that simplifies the design, development, and maintenance of web-based user interfaces.\n</p>",
        " ",
        {
            html: "<ul />",
            content: [
                " ",
                "<li>\n        Create UI in a markup language that’s HTML + extensions for creating\n        your own tags. This markup is easy to write, read, share, and maintain.\n        As with HTML, a single file keeps the related CSS, DOM elements, and\n        JavaScript behavior together. \n    </li>",
                " ",
                "<li>\n        The tags you create, called controls, cleanly define a portion of a\n        page that can be reused. Controls are modular, composable, and subclassable.\n    </li>",
                " ",
                "<li>\n        Write markup in your favorite IDE, then compile it using the QuickUI\n        tools (on Windows, OS/X, or Linux) into highly legible and debuggable JavaScript classes.\n    </li>",
                " ",
                "<li>\n        Define a programmatic interface for your controls that lets them be\n        manipulated without exposing irrelevant implementation details. This\n        avoids fragile code dependencies that impair reusability and\n        maintainability.\n    </li>",
                " ",
                {
                    html: "<li />",
                    content: [
                        " QuickUI builds upon ",
                        {
                            control: "Link",
                            href: "http://jquery.com",
                            content: "jQuery"
                        },
                        ", adding a fully object-oriented and extensible control framework. Use all the goodness of object-oriented design to create well-factored UI code. "
                    ]
                },
                " ",
                "<li>\n        Create top-level pages in QuickUI, or include QuickUI controls in pages\n        built with other tools.\n    </li>",
                " ",
                "<li>\n        Works with Apple Safari, Google Chrome, Internet Explorer (8/9), and\n        Mozilla Firefox. \n    </li>",
                " "
            ]
        },
        " ",
        "<p>\nThe page you are reading now (and this entire site) is built using QuickUI.\nThe following brief demos of various QuickUI aspects each show the live output\nof a QuickUI control running on this page.\n</p>",
        " ",
        {
            control: "FeatureHtmlMacros"
        },
        " ",
        {
            control: "FeatureMarkupAndCSS"
        },
        " ",
        {
            control: "FeatureComposition"
        },
        " ",
        {
            control: "FeatureElementIDs"
        },
        " ",
        {
            control: "FeatureProperties"
        },
        " ",
        {
            control: "FeatureSubclassing"
        },
        " ",
        {
            control: "FeatureScoping"
        },
        " ",
        {
            control: "FeatureBrowserIsolation"
        },
        " ",
        "<h2 class=\"section\">Next steps</h2>",
        " ",
        {
            html: "<p />",
            content: [
                " The ",
                {
                    control: "Link",
                    href: "/markup/tutorial",
                    content: "tutorial"
                },
                " walks through the development of a simple control step-by-step. You can see some sample and ready-to-use QuickUI controls in the ",
                {
                    control: "Link",
                    href: "/catalog",
                    content: "Catalog"
                },
                ". "
            ]
        },
        " ",
        {
            html: "<p />",
            content: [
                " QuickUI is completely free, and the ",
                {
                    control: "Link",
                    href: "https://github.com/JanMiksovsky/quickui",
                    content: "source code"
                },
                " is open under the ",
                {
                    control: "Link",
                    href: "http://www.opensource.org/licenses/mit-license.php",
                    content: "MIT License"
                },
                ". "
            ]
        },
        " ",
        {
            html: "<p />",
            content: [
                " ",
                {
                    control: "Link",
                    href: "/downloads",
                    content: "Download QuickUI"
                },
                " "
            ]
        },
        " ",
        "<br />",
        " ",
        {
            control: "AddThis"
        },
        " "
    ]
});

//
// OrangeDialog
//
var OrangeDialog = Dialog.subclass({
    className: "OrangeDialog",
    content: [
        " ",
        {
            html: "<h1 />",
            id: "OrangeDialog_title"
        },
        " ",
        {
            html: "<div />",
            id: "OrangeDialog_content"
        },
        " ",
        {
            html: "<div />",
            id: "OrangeDialog_buttons"
        },
        " "
    ]
});
OrangeDialog.prototype.extend({
    buttons: Control.chain("$OrangeDialog_buttons", "content"),
    content: Control.chain("$OrangeDialog_content", "content"),
    title: Control.chain("$OrangeDialog_title", "content")
});

//
// Recipe
//
var Recipe = Control.subclass({
    className: "Recipe",
    content: [
        " ",
        {
            html: "<div />",
            content: [
                " Name: ",
                {
                    html: "<span />",
                    id: "Recipe_name"
                },
                " ",
                {
                    html: "<span />",
                    id: "Recipe_rating"
                },
                " "
            ]
        },
        " ",
        {
            html: "<div />",
            id: "Recipe_content"
        },
        " "
    ]
});
Recipe.prototype.extend({
    content: Control.chain("$Recipe_content", "content"),
    name: Control.chain("$Recipe_name", "content"),
    rating: Control.property.integer(function(rating) {
        this.$Recipe_rating().text("*****".substr(0, rating));
    })
})

//
// Red
//
var Red = Control.subclass({
    className: "Red",
    content: " <div class=\"message\">I’m red</div> "
});

//
// Sample
//
var Sample = Control.subclass({
    className: "Sample",
    content: [
        " ",
        "<h1>QuickUI sample</h1>",
        " ",
        {
            control: "Greet"
        },
        " "
    ]
});

//
// SampleDialog
//
var SampleDialog = OrangeDialog.subclass({
    className: "SampleDialog",
    title: "What do you think?",
    buttons: [
        " ",
        {
            control: "OrangeButton",
            content: "Huh"
        },
        " ",
        {
            control: "OrangeButton",
            content: "Neat!"
        },
        " "
    ],
    content: " It's easy to use subclassing to create a new dialog -- or an entirely new template.  "
});
SampleDialog.prototype.extend({
    initialize: function() {
        this._super();
        var self = this;
        this.$OrangeDialog_buttons().click(function() {
            self.close();
        })
    }
});

//
// SearchBox
//
var SearchBox = Control.subclass({
    className: "SearchBox",
    content: [
        " ",
        {
            html: "<input type=\"text\" />",
            id: "terms"
        },
        " ",
        {
            control: "OrangeButton",
            id: "buttonSearch",
            content: "Search"
        },
        " "
    ]
});
SearchBox.prototype.extend({
    
    initialize: function() {
        var self = this;
        this.$buttonSearch().click(function() {
            self._navigate();
        });
        this.$terms().bind("change keydown keyup", function(event) {
            var content = self.content();
            var isContentEmpty = !(content && content.length > 0);
            var keyCode = event.keyCode || event.which;
            if (!isContentEmpty && keyCode === 13 /* Enter */)
            {
                self._navigate();
            }
        });
    },
    
    _navigate: function() {
        var terms = this.$terms().content();
        var query = "http://www.google.com/search?q=%s";
        window.location.href = query.replace("%s", terms);
    }
});

//
// SpriteButton
//
var SpriteButton = BasicButton.subclass({
    className: "SpriteButton",
    content: [
        " ",
        {
            control: "Sprite",
            id: "backgroundLeft"
        },
        " ",
        {
            control: "Sprite",
            id: "backgroundRight"
        },
        " ",
        {
            html: "<button />",
            id: "SpriteButton_content"
        },
        " "
    ]
});
SpriteButton.prototype.extend({
    
    content: Control.chain("$SpriteButton_content", "content"),
    image: Control.chain("$sprites", "image"),

    initialize: function() {
        this._super();
        var self = this;
        this.$SpriteButton_content()
            .blur(function() { self.blur(); })
            .focus(function() { self.focus(); });
    },
    
    cellHeight: Control.chain("css/height", function(value) {
        this.$SpriteButton_content().height(value + "px");
        this.$sprites().cellHeight(value);
    }),
    
    disabled: function(value) {
        if (value !== undefined)
        {
            this.$SpriteButton_content().attr("disabled", String(value) == "true");
        }
        return this._super( value );
    },
    
    $sprites: function() {
        return this.children().filter(".Sprite").cast();
    },
    
    _renderButtonState: function(buttonState) {
        this.$sprites().currentCell(buttonState);
    }

});

//
// OrangeButton
//
var OrangeButton = SpriteButton.subclass({
    className: "OrangeButton",
    image: "url(home/features/buttonStates.png)",
    cellHeight: "32"
});


