/*
    name : linkCapsule
    file : jquery.linkCapsule.js
    author : gregory tomlinson
    copyright: (c) 2010 bit.ly
    Dual licensed under the MIT and GPL licenses.
    ///////////////////////////
    ///////////////////////////        
    dependencies : jQuery 1.4.2, jquery.cookie.js, utilties/ZeroClipboard.js, jquery.escapeHTML.js
    ///////////////////////////
    ///////////////////////////
    
*/

(function($) {
    
    $.fn.linkCapsule = function( capsuleElement, options ) {
        // extend the defaults settings
        var el = this, capsule_element = capsuleElement || ".shortenedBitlyListListBox", 
        o = $.extend(true, defaults, options), shortenedItemListOpen=false,
        capsule = el.find( capsule_element ), links=[], latestShortenLink = {},
        NO_BOX_STATE = 1,
        BOX_NO_LINK_STATE=2,
        BOX_COPY_STATE=3,
        LINK_EDIT_STATE=4;
        if(!capsule) return;
                
        capsule.html( render_State_NoLinks() );    
        ZeroClipboard.setMoviePath('/s/flash/zeroclipboard/ZeroClipboard.swf');   
        
        /******************** 
            Listener: Shorten Complete 
                This is where the KEYWORD Heavy lifting happends
        ****************************************/
        el.bind("customNameComplete", function(e,data) {
            /*
                This event is only intended to be received when the bento box plugin 
                gets a successful connection from the server
                
            */
            var copyButtonAnimation, $elem = el.find('.linkCapsule_topLevelContainer').eq( data.position ),
                text = (data.position === 0) ? "Your Link" : null
                saved_data = $elem.data('meta'), linkCapsule = render_linkCapsule_state_1( data, 3, null, text );
            $elem.replaceWith( linkCapsule );
            
            
            
            saved_data.keyword = data.keyword;
            saved_data.url = data.url;            
            linkCapsule.data('meta', saved_data);
            linkCapsule.linkCapsule_Copy( data.url )
            
            copyButtonAnimation = linkCapsule.find('.copyButtonAnimation');
            animateCopyTextFlag( copyButtonAnimation );
            
            links.unshift( latestShortenLink );                        
            
        });
        
        /****
            Heavy lifting for new shortens
        ***/
        el.bind('shortenComplete', function(e,data) {
            if(!data) return;
            latestShortenLink = data;

            if(links.length <= 0 ) {
                
                //el.trigger('firstShortenComplete', data )
                
                var $p = el.find('.render_State_NoLinks'), saved_data = $p.data('meta'), linkCapsule;


                if( saved_data && saved_data.customNameState ) {
                    var state = BOX_COPY_STATE, keyword = $p.find('.customNameCreationForm input').val();
                    if(keyword !== '') {
                        state = saved_data.customNameState
                    }
                    linkCapsule = render_linkCapsule_state_1( data, state, keyword,  "Your Link" );
                    
                } else {
                    state = BOX_COPY_STATE
                    linkCapsule = render_linkCapsule_state_1( data, BOX_COPY_STATE, null, "Your Link" );
                }

                $p.replaceWith( linkCapsule );
                
                if(state == BOX_COPY_STATE) {
                    linkCapsule.linkCapsule_Copy( data.url )                    
                } else {
                    linkCapsule.find('.customNameCreationForm').bind('submit', function(e) {
                         e.preventDefault();
                         // triggered when hitting enter in the 'custom name' form field
                         var $this = $(this);

                        _addCustomNameActionClickEvent_helper( $this, linkCapsule  );                
                    });                    
                }

                /*
                    Have to put the 'submit' Here because submit doesn't bubble up the DOM.
                    
                    Cannot use .live() with the submit event
                */

                
                copyButtonAnimation = linkCapsule.find('.copyButtonAnimation');
                animateCopyTextFlag( copyButtonAnimation );                
                
                          
                    
            } else {
                
                var linkCapsule = render_linkCapsule_state_1( data, BOX_COPY_STATE, null, "Your Link" ).prependTo( capsule );
                linkCapsule.data( "meta", data )
                linkCapsule.linkCapsule_Copy( data.url )

            }
            
            var copyButtonAnimation = linkCapsule.find('.copyButtonAnimation');
            animateCopyTextFlag( copyButtonAnimation );
            
            links.unshift( latestShortenLink );
            closeAllOpenOptionsDropDowns();
            
            
            el.find('.linkCapsule_whiteContainer').eq(1).find('.linkCapsule_explainerText').html('')
            
            
        });
        

        /***********************************************
            Attach General Plugin 
                Event Listeners  
                
        ************************************************/



        /**********  STATE 1 ***/
        el.find('.initializeCustomNameField a').live('click', function(e) {
            e.preventDefault();
            // add the editable box here
            console.log('Hard Coded Domain: bit.ly ')
            var $this = $(this), $p = $this.parents('.linkCapsule_topLevelContainer'), link_data = {}, domain = "bit.ly/", htmlFrame = "";


            htmlFrame +=  _renderLinkState2( domain, "" );
            //$p.find('.linkCapsule_displayLinkContainer').replaceWith( $( htmlFrame )  );     
            var inputBox = $(htmlFrame).insertBefore( $this.parents('.linkCapsule_buttonContainer') );
            $p.find('.linkCapsule_buttonContainer').replaceWith( $(render_customButton_state(2) ) );  
            inputBox.find('input').focus();            
            $p.linkCapsule_Animation();
            $p.data('meta', { customNameState : LINK_EDIT_STATE });
                                   
            $p.find('.customNameCreationForm').bind('submit', function(e) {
                 e.preventDefault();
                 // triggered when hitting enter in the 'custom name' form field
                 var $this = $(this);
                 $this.trigger('errorMessage', {
                     text : "You'll also need to enter a long link" 
                 })
                //_addCustomNameActionClickEvent_helper( $this, $p  );                
            });
            
            el.trigger('track', { 'plugin:linkCapsule' : 'Customize Button Clicked Before Link Shortened : State 1' } )            

        });
        
        
        /**********  STATE 2 ***/        
        el.find('.intializeCustomFieldWithNoLink').live('click', function(e) {
            e.preventDefault();
            $p = $(this).parents('.linkCapsule_topLevelContainer')
            $p.replaceWith($( render_State_NoLinks() ) )
            // prevent event bubbling and propogation
            
            $p.data('meta', { customNameState : LINK_EDIT_STATE })            
            
            el.trigger('track', { 'plugin:linkCapsule' : 'Cancel Customize Button Clicked Before Link Shortened : State 2' } )                        
            return false;
        })    

        /**********  STATE 3 ***/
        el.find('.enableCustomNameField a').live('click', function(e) {
            e.preventDefault();
            // add the editable box here
            var $this = $(this), $p = $this.parents('.linkCapsule_topLevelContainer'), link_data = $p.data('meta'), 
                 pos = link_data.url.lastIndexOf('/'), domain = link_data.url.substring(7,pos) + "/", htmlFrame = "";

            
            if($p) {
                htmlFrame +=  _renderLinkState2( domain, link_data.keyword || link_data.hash );
                $p.find('.linkCapsule_displayLinkContainer').replaceWith( $( htmlFrame )  );     
                $p.find('.linkCapsule_buttonContainer').replaceWith( $(render_customButton_state( LINK_EDIT_STATE ) ) );              
            } 
            
            $p.find('.customNameCreationForm').bind('submit', function(e) {
                 e.preventDefault();
                 // triggered when hitting enter in the 'custom name' form field
                 var $this = $(this);

                _addCustomNameActionClickEvent_helper( $this, $p  );                
            }); 
            $p.linkCapsule_Animation();
            copyButtonAnimation = $p.find('.copyButtonAnimation');
            animateCopyTextFlag( copyButtonAnimation );   
            
            el.trigger('track', { 'plugin:linkCapsule' : 'Customize Button Clicked  : State 3' } )                                                        

        });
        
        
        
        
        /**********  STATE 4 ***/        
        el.find('.saveCustomNameField').live('click', function(e) {
           e.preventDefault(); 
           var $this = $(this), $p = $this.parents('.linkCapsule_topLevelContainer');
           _addCustomNameActionClickEvent_helper( $this, $p  ); 
           
            el.trigger('track', { 'plugin:linkCapsule' : 'Save Button Clicked  : State 4' } );
            
                        
                        
        });

    
        return this;
        
        
        /******************** EVENTS ****************************************/
        
                                
        function _addCustomNameActionClickEvent_helper( $elem, $parent ) {
            var value = $parent.find('.linkCapsule_state2_inner input').val(),
                meta = $parent.data('meta'), data = $.extend({}, meta, { 'keyword' : value } );
             
             
             console.log(meta, data)
                
            /*
                if the user hasn't changed the value and presses 'save' it should switch back to copy state: AKA green box
            */
            if(meta.hash === $.trim( value ) ) {
                // flip it over to the over view!.
                
                
                $p = el.find('.linkCapsule_topLevelContainer');                
                linkCapsule = render_linkCapsule_state_1( data, BOX_COPY_STATE, null, "Your Link" );
                $p.replaceWith( linkCapsule );                
                var copyButtonAnimation = linkCapsule.find('.copyButtonAnimation');
                linkCapsule.linkCapsule_Copy( data.url )
                animateCopyTextFlag( copyButtonAnimation );
                
                return;
            }
            
            
            
            
            var all_linkcapsules = el.find('.linkCapsule_topLevelContainer'), 
                pos = jQuery.inArray( $parent[0], all_linkcapsules )
            data.position = pos;
            $elem.trigger('saveCustomName', data );            
        }
                
        function closeAllOpenOptionsDropDowns() {
            el.find('.shortenedLinkOptionsDropDownSecondLevel_open')
                .removeClass('shortenedLinkOptionsDropDownSecondLevel_open').css('display', 'none');            
        }
        
        
        /***************** ANIMATIONS **************************/
        
        function animateCopyTextFlag( elem ) {
            if (!FlashDetect.installed) {
                /* skip copyText animation if we don't have flash */
                return;
            }
            var teaserButton = elem, timeout;
            console.log(teaserButton)
            setTimeout(function(){
                
                teaserButton.animate({
                    right:0
                }, 300, function() {
                    // retract it now!!
                    timeout = setTimeout(function() {
                        teaserButton.animate({
                            right:'-85'
                        }, 400);
                    }, 1500)
                })

            }, 400)

      
        }
        
        /************ RENDER ******************************************/
        
        
        /***  STATES: 
                These are 'top level' states, meaning they are whole chunks to place on the page as a unit.
                
                
        **/
        
        function render_infopage_promo( long_url, short_url ) {
            var html = "", short_length = short_url.length, long_length = long_url.length, 
                safe_long_url = $.escapeHTML( long_url ),
                urlSpaceRemaining = o.maxPromoLength - o.txt.infopromo.length - o.txt.longpromo.length - short_length,                
                trimmed_long_url = trimLongUrl( safe_long_url, urlSpaceRemaining );
                
            html += '<div class="linkCapsule_infopage_promo">'
                html += o.txt.infopromo + ' <a title="Get real-time metrics about: '+ safe_long_url +'" href="'+short_url+'+">' + short_url +'+</a> ';
                html += '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
                html += ' Long Link: <a href="'+safe_long_url+ '" title="'+safe_long_url+'">' + trimmed_long_url + '</a>'
            html += '</div>'
            console.log(urlSpaceRemaining, short_url)
            
            return html;
            
        }
        
        function trimLongUrl( str, length ) {
            /* utility used for  FUNCTION: render_infopage_promo  */
            console.log(str, length)
            if(!str) return "";
            return (str.length > length) ? str.substring(0,length-3) + '...' : str;
            
        }
        
        
        function render_State_NoLinks() {
            /*
                1. Drop down w/ copy button selected state
                2. Grey 'Go' Button
            */
            var html = '<div class="render_State_NoLinks linkCapsule_topLevelContainer">';
                    html += render_customButton_state( NO_BOX_STATE );
                    html += '<div class="hr"><hr /></div>'
                html += '</div>';
                
            return html;
        }
        
        function render_customButton_state( state ) {
            var html = "", text = "Customize", cssClass = "initializeCustomNameField", title="";

            switch (state) {
                
                
                case NO_BOX_STATE:
                    cssClass = "initializeCustomNameField";
                    title = "Create a bit.ly link with a custom name"
                break;
                
                case BOX_NO_LINK_STATE:
                    cssClass = "intializeCustomFieldWithNoLink"
                    text = "Cancel"
                    title = "Cancel custom keyword edit"                    
                break;
                
                case BOX_COPY_STATE:
                    cssClass = "enableCustomNameField";
                    title = "Give your bit.ly link a custom name"
                break;
                
                case LINK_EDIT_STATE:
                    cssClass = "saveCustomNameField";
                    text = "Save";
                    title = "Save your custom name"                    
                break;
                
                default:
                
                break;
                
            }


            html += '<div class="linkCapsule_buttonContainer '+cssClass+'">';
                html += '<a title="'+title+'" type="customize_button" class="" href="#">'+text+'</a>';
                html += '<div class="hr"><hr /></div>';
            html += '</div>';
            
            return html;
        }
        
                
        function render_linkCapsule_state_1( data, state, keyword, text ) {
            console.log(data, 'render_linkCapsule_state_1')
            var kword = (keyword) ? keyword : data.keyword || data.hash, txt = text || "&nbsp;",
                save_long_url = $.escapeHTML( data.long_url );
            /*
                1. white container
                2. bit.ly link
                    - Copy or Edit 
                3. customize | save button
                4. animation flag
                
                promo line: Get real-time stats: http://gt-co.de/hash
                
                // shareMessages.js attaches below this class
            */
            var html = '<div class="linkCapsule_topLevelContainer" hash="'+ (kword) +'">';
                html += '<div class="linkCapsule_whiteContainer" >'
                    html += '<b class="linkCapsule_whiteContainer_leftEdge"></b>'
                    html += '<b class="linkCapsule_whiteContainer_rightEdge"></b>'                    
                    html += "<span class='linkCapsule_explainerText'>"+txt+"</span>"
                    
                    if( state === BOX_COPY_STATE) {
                        html += _renderLinkState1( data.url )
                    } else {
                        
                        html += _renderLinkState2( "bit.ly/", kword ) // get the domain and hash here...
                    }
                
                    html += render_customButton_state(state);

                    html += '<div class="hr"><hr /></div>'
                    html += '</div>'
                    html += render_infopage_promo( data.long_url, data.url );
                html += '</div>'
                
            var $html = $(html);           
            
            $html.linkCapsule_Animation();
            $html.data('meta',data);
            return $html;
        }

                
        function _renderLinkState1( url ) {
            var html = '';
            
            html += '<div class="shortenedLinkState1 linkCapsule_displayLinkContainer">';
                //html += '<div class="mainShareFlashCopyButtonBox" id="main_copy_button"></div>';

                
                html += '<div class="shortenedLinkState1_viewWindow"></div>'
                html += '<span class="shortenedLinkState1_url"><input type="text" value="' + url + '" name="" /></span>';
                html += '<div class="copyButtonAnimation"><span class="copyButtonAnimationText">Click to Copy</span></div>'
                
                
                
            html += '</div>';

            
            
            return html;
        }
        
        function _renderLinkState2( domain, hash ) {
            var html = '';
            html += '<div class="shortenedLinkState2 linkCapsule_displayLinkContainer">'         
                html += '<div class="linkCapsule_state2_inner">'
                    html += '<span>'+domain+'</span>'
                    html += '<form class="customNameCreationForm">'
                        html += '<input class="keywordInputField" type="text" name="" value="'+ hash +'" />'
                    html += '</form>'
                html += '</div>'
                
                html += '<div class="shortenedLinkState1_viewWindow"></div>'
                html += '<div class="copyButtonAnimation"><span class="copyButtonAnimationText">Edit Your Link</span></div>'                

            html += '</div>'
            
            return html;
        }
        
             
    }
    
    
    /*
        jquery.linkCapsule_Animation.js
        This helper function directly effects it's parent plugin
        
            This style is NON standard, exploring nested function usage to make APP more 'bit' sized

    */
    
    $.fn.linkCapsule_Animation = function(options) {
        var $el = this, o = $.extend({}, defaults, options), $p = $el.parent(),
            $editable, copyButton = $p.find('.copyButtonAnimation');
        
        $editable = $el.find('.keywordInputField');
        if($editable.length>0) {
            $editable.hover(function(e){
                copyButton.animate({
                    right:0
                }, 300)                        
            },function(e){
                copyButton.animate({
                    right:'-85'
                }, 200)                        
            })                
        }
        
        $editable.focus();
        $editable.bind('keypress', function(e) {
            console.log('thi is chnaing')
            $editable.unbind();
            copyButton.animate({
                right:'-85'
            }, 200);            
        });
        
        return this;
        
    }
    
    $.fn.linkCapsule_Copy = function( url, options) {
        var $el = this;
        var copyButtonAnimation, clipboard = null, flashHTML = null; 
        if (!FlashDetect.installed){
            // turn off the div that hids the input field so it can by copy & pasted
            $el.find('.shortenedLinkState1_viewWindow').hide();
            return;
        }
        if(url !== '') {
            clipboard = new ZeroClipboard.Client();
            flashHTML = clipboard.getHTML(262, 30);
            //
            clipboard.addEventListener('load', function() {
              clipboard.setText( url );      
            });
            
            clipboard.setHandCursor( true );                                
            copyButtonAnimation = $el.find('.copyButtonAnimation');                    
            clipboard.addEventListener( 'onMouseOver', function(e) {

                copyButtonAnimation.animate({
                    right:0
                }, 300)            

            } ); 
            
            clipboard.addEventListener( 'onComplete', function(e) {
                $el.trigger('successMessage', {
                    text : 'Successfully copied '+ url + ' to clipboard'
                })
            } );                    
            
            clipboard.addEventListener( 'onMouseOut', function(e) {
                copyButtonAnimation.animate({
                    right:'-85'
                }, 200)            

            } );  
            
            clipboard.glue( $el.find('.shortenedLinkState1_viewWindow')[0], $el.find('.shortenedLinkState1')[0] )     
            clipboard.setText( url );                      
        }        
        
    }
    
    
    
    
    var defaults = {
        linkLimit : 3,
        debug : true,
        url : '',
        params : {
            
        },
        maxPromoLength : 72,
        txt : {
            infopromo : 'Get real-time stats:',
            longpromo : 'Long Link:'
        }
        
    }, $bod;
    
})(jQuery);
