define( [
    "jquery"
],
    function (jq) {

        "use strict";

        /**
         * @constructor
         */

        return function ( options, context, metadata ) {
            var textboxDiv,
                timeLiveUpdater,
                dateLiveUpdater,
                fonts = [
                    'Arial, Helvetica, sans-serif',
                    '"Times New Roman", Times, serif',
                    'Verdana, Geneva, sans-serif',
                    '"Courier New", Courier, monospace',
                    'Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif',
                    '"Droid Serif", "Times New Roman", Times, serif'
                ];

            function getFont( index ) {
                var fontIndex = ( index > 0 && index < fonts.length ) ? index - 1 : 0;
                return fonts[fontIndex];
            }

            function asRgbaValue( color, transparency ) {

                var color = hexToRgb( color ),
                    alpha = asAlpha( transparency );

                return "rgba(" + color.r + ", " + color.g + ", " + color.b + ", " + alpha + ")";
            }

            function hexToRgb( hex ) {
                var parsingResult = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec( hex );
                return parsingResult ? {
                    r: parseInt( parsingResult[1], 16 ),
                    g: parseInt( parsingResult[2], 16 ),
                    b: parseInt( parsingResult[3], 16 )
                } : {
                        r: 0,
                        g: 0,
                        b: 0
                    };
            }

            function asAlpha( percentValue ) {
                return ( 100 - percentValue ) / 100;
            }

            function createDateVariable() {
                textboxDiv = jq( document.createElement( "div" ) )
                    .css( {
                        "width": "100%",
                        "height": "100%",
                        "background-color": asRgbaValue( options.autoform.backgroundColor, options.autoform.backgroundTransparency ),
                        "font-family": getFont(options.text.fontFamily ),
                        "font-size": options.text.fontSize + "px",
                        "font-weight": "normal",
                        "font-style": "normal",
                        "color": options.text.color,
                        "line-height": options.text.fontSize + "px",
                        "padding-left": ( options.text.paddingLeft - parseInt( options.autoform.borderSize ) ) + "px",
                        "padding-right": ( options.text.paddingRight - parseInt( options.autoform.borderSize ) ) + "px",
                        "padding-top": ( options.text.paddingTop - parseInt( options.autoform.borderSize ) ) + "px",
                        "padding-bottom": ( options.text.paddingBottom - parseInt( options.autoform.borderSize ) ) + "px",
                        "text-align": options.text.textAlign,
                        "box-sizing": "border-box",
                        "border": ( options.autoform.borderSize > 0 ) ? options.autoform.borderSize + "px solid " + asRgbaValue( options.autoform.borderColor, options.autoform.borderTransparency ) : "0",
                        "-webkit-transform": "rotate(" + parseInt( options.settings.rotation ) + "deg)",
                        /* Saf3.1+, Chrome */
                        "-moz-transform": "rotate(" + parseInt( options.settings.rotation ) + "deg)",
                        /* FF3.5+ */
                        "-ms-transform": "rotate(" + parseInt( options.settings.rotation ) + "deg)",
                        /* IE9 */
                        "-o-transform": "rotate(" + parseInt( options.settings.rotation ) + "deg)",
                        /* Opera 10.5 */
                        "transform": "rotate(" + parseInt( options.settings.rotation ) + "deg)"
                    } )
                    .html( "" );

                if ( options.text.isBold ) { textboxDiv.css( { "font-weight": "bold" } ) };
                if ( options.text.isItalic ) { textboxDiv.css( { "font-style": "italic" } ) };
                if ( options.text.isUnderline ) { textboxDiv.css( { "text-decoration": "underline" } ) };

                switch ( options.valueSelect ) {
                    case 0:
                        textboxDiv.html( getDate() );
                        break;
                    case 1:
                        textboxDiv.html( getTime() );
                        break;
                    default:
                        textboxDiv.html( getDate() );
                        break;
                } 
            }

            function getDayName( date, locale ) {
                return date.toLocaleDateString( locale, { weekday: 'long' } );
            }

            function getMonthName( date, locale ) {
                return date.toLocaleDateString( locale, { month: 'long' } );
            }

            function getDate() {
                var result,
                    date,
                    currentDate = new Date(),
                    currentDay,
                    currentMonth,
                    currentYear,
                    contentLanguage = metadata.stage.getContentLanguage(),
                    isMonthAsName = options.date.monthAsName;

                currentDate.setDate( currentDate.getDate() + parseInt( options.date.delta ) );
                currentDay = currentDate.getDate();
                currentMonth = currentDate.getMonth() + 1; //As January is 0.
                currentYear = currentDate.getFullYear();

                if ( options.date.leadingZero ) {
                    if ( currentDay < 10 ) {
                        currentDay = "0" + currentDay;
                    }
                    if ( currentMonth < 10 ) {
                        currentMonth = "0" + currentMonth;
                    }
                }

                date = {
                    day: currentDay,
                    month: currentMonth,
                    year: currentYear,
                    separator: options.date.separator,
                    dayName: getDayName( currentDate, contentLanguage ),
                    monthName: getMonthName( currentDate, contentLanguage )
                }

                switch ( options.date.format ) {
                    //day/month/year
                    case 0:
                        if ( isMonthAsName ) {
                            result = date.day + date.separator + date.monthName + date.separator + date.year;
                        } else {
                            result = date.day + date.separator + date.month + date.separator + date.year;
                        }
                        break;
                    //month/day/year
                    case 1:
                        if ( isMonthAsName ) {
                            result = date.monthName + date.separator + date.day + date.separator + date.year;
                        } else {
                            result = date.month + date.separator + date.day + date.separator + date.year;
                        }
                        break;
                    //year/month/day
                    case 2:
                        if ( isMonthAsName ) {
                            result = date.year + date.separator + date.monthName + date.separator + date.day;
                        } else {
                            result = date.year + date.separator + date.month + date.separator + date.day;
                        }
                        break;
                    //year
                    case 3:
                        result = date.year;
                        break;
                    //month
                    case 4:
                        if ( isMonthAsName ) {
                            result = date.monthName;
                        } else {
                            result = date.month;
                        }
                        break;
                    //day
                    case 5:
                        result = date.day;
                        break;
                    //day-name
                    case 6:
                        result = date.dayName;
                        break;
                    //year/month/day
                    default:
                        if ( isMonthAsName ) {
                            result = date.day + date.separator + date.month + date.separator + date.year;
                        } else {
                            result = date.day + date.separator + date.monthName + date.separator + date.year;
                        }
                        break;
                }

                return result;
            }

            function getTime() {
                var result,
                    time,
                    currentDate = new Date(),
                    currentHour,
                    currentMiddayHour,
                    currentMinute,
                    currentSecond,
                    currentMidday,
                    isAmPm = options.time.ampmFormat;

                currentDate.setSeconds( currentDate.getSeconds() + parseInt( options.time.delta ) );
                currentHour = currentDate.getHours();
                currentMinute = currentDate.getMinutes();
                currentSecond = currentDate.getSeconds();

                currentMidday = currentHour >= 12 ? "pm" : "am";
                currentMiddayHour = ( currentHour % 12 ) ? ( currentHour % 12 ) : 12;

                if ( options.time.leadingZero ) {
                    if ( currentHour < 10 ) {
                        currentHour = "0" + currentHour;
                    }
                    if ( currentMiddayHour < 10 ) {
                        currentMiddayHour = "0" + currentMiddayHour;
                    }
                    if ( currentMinute < 10 ) {
                        currentMinute = "0" + currentMinute;
                    }
                    if ( currentSecond < 10 ) {
                        currentSecond = "0" + currentSecond;
                    }
                }

                time = {
                    hour: currentHour,
                    middayHour: currentMiddayHour,
                    minute: currentMinute,
                    second: currentSecond,
                    separator: options.time.separator,
                    midday: currentMidday
                }

                switch ( options.time.format ) {
                    //hour/minute/second
                    case 0:
                        if ( isAmPm ) {
                            result = time.middayHour + time.separator + time.minute + time.separator + time.second + " " + time.midday;
                        } else {
                            result = time.hour + time.separator + time.minute + time.separator + time.second;
                        }
                        break;
                    //hour/minute
                    case 1:
                        if ( isAmPm ) {
                            result = time.middayHour + time.separator + time.minute + " " + time.midday;
                        } else {
                            result = time.hour + time.separator + time.minute;
                        }
                        break;
                    //hour
                    case 2:
                        if ( isAmPm ) {
                            result = time.middayHour + " " + time.midday;
                        } else {
                            result = time.hour;
                        }
                        break;
                    //minute
                    case 3:
                        result = time.minute;
                        break;
                    //second
                    case 4:
                        result = time.second;
                        break;
                    //hour/minute/second
                    default:
                        if ( isAmPm ) {
                            result = time.middayHour + time.separator + time.minute + time.separator + time.second + " " + time.midday;
                        } else {
                            result = time.hour + time.separator + time.minute + time.separator + time.second;
                        }
                        break;
                }

                return result;
            }

            function startLiveUpdater() {
                stopLiveUpdater();

                switch ( options.valueSelect ) {
                    case 0:
                        setInterval( function () {
                            textboxDiv.html( getDate() );
                        }, 1000 );
                        break;
                    case 1:
                        setInterval( function () {
                            textboxDiv.html( getTime() );
                        }, 1000 );
                        break;
                    default:
                        setInterval( function () {
                            textboxDiv.html( getTime() );
                        }, 1000 );
                        break;
                }
            }

            function stopLiveUpdater() {
                if ( dateLiveUpdater ) {
                    clearInterval( dateLiveUpdater );
                    dateLiveUpdater = null;
                }
                if ( timeLiveUpdater ) {
                    clearInterval( timeLiveupdater );
                    timeLiveupdater = null;
                }
            }

            return {

                build: function () {

                    createDateVariable();

                    return {
                        getElement: function () {
                            return textboxDiv;
                        },
                        startLiveUpdate: function () {
                            startLiveUpdater();
                        },
                        stopLiveUpdate: function () {
                            stopLiveUpdater();
                        }
                    }
                }
            }
        }
    } );
