// -------------------------------------------------------------------------- \\
// File: NotificationView.js                                                  \\
// Module: PanelViews                                                         \\
// Requires: Core, Foundation, DOM, View                                      \\
// Author: Neil Jenkins                                                       \\
// License: © 2010–2013 Opera Software ASA. All rights reserved.              \\
// -------------------------------------------------------------------------- \\

"use strict";

( function ( NS, undefined ) {

var hiddenLayout = {
    top: 0
};

var NotificationView = NS.Class({

    Extends: NS.View,

    Mixin: NS.AnimatableView,

    animateLayerDuration: 200,

    className: function () {
        return 'NotificationView' +
            ( this.get( 'userMayClose' ) ? ' closable' : '' );
    }.property( 'userMayClose' ),

    destroyOnClose: true,

    isShowing: false,
    userMayClose: true,
    precedence: 0,
    timeout: 0,

    text: '',
    html: '',

    _timer: null,

    show: function ( notificationsContainer ) {
        notificationsContainer.insertView( this );
        this.set( 'layout', {
            top: this.get( 'pxHeight' )
        });
        var timeout = this.get( 'timeout' );
        if ( timeout ) {
            this._timer =
                NS.RunLoop.invokeAfterDelay( this.hide, timeout, this );
        }
        return this.set( 'isShowing', true );
    },

    hide: function () {
        this.set( 'isShowing', false );
        if ( this._timer ) {
            NS.RunLoop.cancel( this._timer );
            this._timer = null;
        }
        return this.set( 'layout', hiddenLayout );
    },

    didAnimate: function () {
        this.increment( 'animating', -1 );
        if ( !this.get( 'animating' ) &&
                this.get( 'layout' ) === hiddenLayout ) {
            this.get( 'parentView' )
                .removeView( this )
                .notificationDidHide( this );

            if ( this.get( 'destroyOnClose' ) ) {
                this.destroy();
            }
        }
    }.queue( 'render' ),

    zIndex: 10000,
    layout: hiddenLayout,

    draw: function ( layer ) {
        this.drawNotification( layer );
        if ( this.get( 'userMayClose' ) ) {
            layer.appendChild(
                NS.Element.create( 'a.close', [
                    NS.loc( 'Close' )
                ])
            );
        }
    },

    drawNotification: function ( layer ) {
        var text = this.get( 'text' ),
            html = this.get( 'html' );
        if ( text || html ) {
            layer.appendChild(
                this._textNode = NS.Element.create( 'span', {
                    text: text || undefined,
                    html: text ? undefined : html
                })
            );
        }
    },

    notificationNeedsRedraw: function ( self, property, oldValue ) {
       return this.propertyNeedsRedraw( self, property, oldValue );
    }.observes( 'text', 'html' ),

    redrawText: function () {
        this.redrawHTML();
    },
    redrawHTML: function () {
        var text = this.get( 'text' ),
            html = this.get( 'html' );
        this._textNode.set( html ? 'html' : 'text', html || text );
    },

    hideOnClick: function ( event ) {
        if ( event.target.className === 'close' ) {
            event.preventDefault();
            this.hide();
        }
    }.on( 'click' )
});

var NotificationContainerView = NS.Class({

    Extends: NS.View,

    showing: null,

    init: function ( mixin ) {
        this._waiting = [];
        NotificationContainerView.parent.init.call( this, mixin );
    },

    positioning: 'absolute',
    layout: {
        bottom: '100%',
        left: '50%'
    },

    willShow: function ( notification ) {
        var showing = this.get( 'showing' );
        if ( showing ) {
            if ( notification !== showing &&
                    notification.get( 'precedence' ) >=
                    showing.get( 'precedence' ) ) {
                this._waiting.push( notification );
                this.hide( showing );
            }
            return false;
        }
        return true;
    },

    show: function ( notification ) {
        if ( this.willShow( notification ) ) {
            this.set( 'showing', notification );
            notification.show( this );
        }
    },

    hide: function ( notification ) {
        var showing = this.get( 'showing' );
        if ( showing && ( !notification || notification === showing ) ) {
            showing.hide();
        }
    },

    notificationDidHide: function ( notification ) {
        this.set( 'showing', null );
        var nextNotification = this._waiting.pop();
        if ( nextNotification ) {
            this.show( nextNotification );
        }
    }
});

NS.NotificationContainerView = NotificationContainerView;
NS.NotificationView = NotificationView;

}( this.O ) );

@@ -1535,39 +1535,438 @@
     
-this.set( 'isShowing', false );
+// If we don't have a layerAnimation object yet, we can't have animated%0A        // in, so just detach immediately. Otherwise, stop the current layer%0A        // animation, then animate out.%0A        var layerAnimation = NS.meta( this, true ).cache.layerAnimation;%0A        if ( layerAnimation ) %7B%0A            layerAnimation.stop();%0A            this.set( 'layout', hiddenLayout );%0A        %7D else %7B%0A            this.detach();%0A        %7D
 %0A   
@@ -2105,37 +2105,33 @@
 s.set( '
-layout', hiddenLayout
+isShowing', false
  );%0A    
@@ -2247,21 +2247,46 @@
 ng' ) &&
-%0A    
+ !this.get( 'isShowing' ) ) %7B%0A
         
@@ -2298,49 +2298,80 @@
 his.
-get( 'layout' ) === hiddenLayout ) %7B%0A    
+detach();%0A        %7D%0A    %7D.queue( 'render' ),%0A%0A    detach: function () %7B%0A
     
@@ -2411,20 +2411,16 @@
         
-    
 .removeV
@@ -2431,20 +2431,16 @@
  this )%0A
-    
         
@@ -2478,28 +2478,24 @@
 );%0A%0A        
-    
 if ( this.ge
@@ -2528,28 +2528,24 @@
             
-    
 this.destroy
@@ -2548,30 +2548,16 @@
 troy();%0A
-            %7D%0A
         
@@ -2563,34 +2563,16 @@
  %7D%0A    %7D
-.queue( 'render' )
 ,%0A%0A    z

Fix race condition in NotificationView.