/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

#include <canvas/debug.hxx>

#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/presentation/XSlideShowView.hpp>

#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <cppcanvas/basegfxfactory.hxx>

#include "activity.hxx"
#include "activitiesqueue.hxx"
#include "slideshowcontext.hxx"
#include "userpaintoverlay.hxx"
#include "mouseeventhandler.hxx"
#include "eventmultiplexer.hxx"
#include "screenupdater.hxx"
#include "vieweventhandler.hxx"

#include <boost/bind.hpp>
#include <boost/noncopyable.hpp>
#include "slide.hxx"
#include "cursormanager.hxx"

using namespace ::com::sun::star;

namespace slideshow
{
    namespace internal
    { 
        class PaintOverlayHandler : public MouseEventHandler,
                                    public ViewEventHandler,
				    public UserPaintEventHandler
        {
        public:
            PaintOverlayHandler( const RGBColor&          rStrokeColor,
                                 double                   nStrokeWidth,
                                 ActivitiesQueue&         rActivitiesQueue,
                                 ScreenUpdater&           rScreenUpdater,
                                 const UnoViewContainer&  rViews,
								 Slide&		              rSlide,
                                 const PolyPolygonVector& rPolygons,
								 bool					  bActive ) :
                mrActivitiesQueue( rActivitiesQueue ),
                mrScreenUpdater( rScreenUpdater ),
                maViews(),
                maPolygons( rPolygons ),
                maStrokeColor( rStrokeColor ),
                mnStrokeWidth( nStrokeWidth ),
                maLastPoint(),
                maLastMouseDownPos(),
                mbIsLastPointValid( false ),
                mbIsLastMouseDownPosValid( false ),
				//handle the "remove all ink from slide" mode of erasing
				mbIsEraseAllModeActivated( false ),
				//handle the "remove stroke by stroke" mode of erasing
				mbIsEraseModeActivated( false ),
				mrSlide(rSlide),
                mnSize(100),
				mbActive( bActive )
            {
                std::for_each( rViews.begin(),
                               rViews.end(),
                               boost::bind( &PaintOverlayHandler::viewAdded,
                                            this,
                                            _1 ));
                drawPolygons();
            }

            virtual void dispose()
            {
                maViews.clear();
            }

            // ViewEventHandler methods
            virtual void viewAdded( const UnoViewSharedPtr& rView )
            {
                maViews.push_back( rView );
            }

            virtual void viewRemoved( const UnoViewSharedPtr& rView )
            {
                maViews.erase( ::std::remove( maViews.begin(),
                                              maViews.end(),
                                              rView ) );
            }

            virtual void viewChanged( const UnoViewSharedPtr& /*rView*/ )
            {
                // TODO(F2): for persistent drawings, need to store
                // polygon and repaint here.
            }
            
            virtual void viewsChanged()
            {
                // TODO(F2): for persistent drawings, need to store
                // polygon and repaint here.
            }
            
			bool colorChanged( RGBColor const& rUserColor )
            {
				mbIsLastPointValid = false;
				mbActive = true;
				this->maStrokeColor = rUserColor;
				this->mbIsEraseModeActivated = false;
                return true;
			}
			
            bool widthChanged( double nUserStrokeWidth )
            {
                this->mnStrokeWidth = nUserStrokeWidth;
                mbIsEraseModeActivated = false;
                return true;
            }
            
			void repaintWithoutPolygons()
			{
                // must get access to the instance to erase all polygon
				for( UnoViewVector::iterator aIter=maViews.begin(), aEnd=maViews.end();
					aIter!=aEnd;
					++aIter )
                {
					// fully clear view content to background color
					//(*aIter)->getCanvas()->clear();

					//get via SlideImpl instance the bitmap of the slide unmodified to redraw it
					SlideBitmapSharedPtr 		 pBitmap( mrSlide.getCurrentSlideBitmap( (*aIter) ) );
					::cppcanvas::CanvasSharedPtr pCanvas( (*aIter)->getCanvas() );
						
					const ::basegfx::B2DHomMatrix 	aViewTransform( (*aIter)->getTransformation() );
					const ::basegfx::B2DPoint 		aOutPosPixel( aViewTransform * ::basegfx::B2DPoint() );
						
					// setup a canvas with device coordinate space, the slide
					// bitmap already has the correct dimension.
					::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( pCanvas->clone() );
						
					pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
						
					// render at given output position
					pBitmap->move( aOutPosPixel );
						
					// clear clip (might have been changed, e.g. from comb
					// transition)
					pBitmap->clip( ::basegfx::B2DPolyPolygon() ); 
					pBitmap->draw( pDevicePixelCanvas );
						
					mrScreenUpdater.notifyUpdate(*aIter,true);
				}
			}

			bool eraseAllInkChanged( bool const& rEraseAllInk )
            {
				this->mbIsEraseAllModeActivated= rEraseAllInk;
				// if the erase all mode is activated it will remove all ink from slide, 
				// therefor destroy all the polygons stored
				if(mbIsEraseAllModeActivated)
                {
					// The Erase Mode should be desactivated
                    mbIsEraseModeActivated = false;
					repaintWithoutPolygons();
					maPolygons.clear();
                }
                mbIsEraseAllModeActivated=false;
                return true;
            }
			
            bool eraseInkWidthChanged( sal_Int32 rEraseInkSize )
            {
                // Change the size
                this->mnSize=rEraseInkSize;
                // Changed to mode Erase
                this->mbIsEraseModeActivated = true;
                return true;
            }

            bool switchPenMode()
            {
				mbIsLastPointValid = false;
				mbActive = true;
                this->mbIsEraseModeActivated = false;
                return true;
            }

            bool switchEraserMode()
            {
				mbIsLastPointValid = false;
				mbActive = true;
                this->mbIsEraseModeActivated = true;
                return true;
            }

            bool disable()
            {
				mbIsLastPointValid = false;
                mbIsLastMouseDownPosValid = false;
				mbActive = false;
                return true;
            }
			
            //Draw all registered polygons.
            void drawPolygons()
            {		
                for( PolyPolygonVector::iterator aIter=maPolygons.begin(), aEnd=maPolygons.end();
                                     aIter!=aEnd;
                                     ++aIter )
                {
                    (*aIter)->draw();
                }
                // screen update necessary to show painting
                mrScreenUpdater.notifyUpdate();	
            }
                       
            //Retrieve all registered polygons.
            PolyPolygonVector getPolygons()
            {
                return maPolygons;	
            }
            
            // MouseEventHandler methods
            virtual bool handleMousePressed( const awt::MouseEvent& e )
            {
				if( !mbActive )
					return false;

                if (e.Buttons == awt::MouseButton::RIGHT)
                {
                    mbIsLastPointValid = false;
                    return false;
                }
                
                if (e.Buttons != awt::MouseButton::LEFT)
					return false;
                
                maLastMouseDownPos.setX( e.X );
                maLastMouseDownPos.setY( e.Y );
                mbIsLastMouseDownPosValid = true;

                // eat mouse click (though we don't process it
                // _directly_, it enables the drag mode
                return true;
            }

            virtual bool handleMouseReleased( const awt::MouseEvent& e )
            {
				if( !mbActive )
					return false;

                if (e.Buttons == awt::MouseButton::RIGHT)
                {
                    mbIsLastPointValid = false;
                    return false;
                }
                
                if (e.Buttons != awt::MouseButton::LEFT)
                    return false;
                
                // check, whether up- and down press are on exactly
                // the same pixel. If that's the case, ignore the
                // click, and pass on the event to low-prio
                // handlers. This effectively permits effect
                // advancements via clicks also when user paint is
                // enabled.
                if( mbIsLastMouseDownPosValid && ::basegfx::B2DPoint( e.X, e.Y ) == maLastMouseDownPos )
                {
                    mbIsLastMouseDownPosValid = false;
                    return false;
                }

                // invalidate, next downpress will have to start a new
                // polygon.
                mbIsLastPointValid = false;

                // eat mouse click (though we don't process it
                // _directly_, it enables the drag mode
                return true;
            }

            virtual bool handleMouseEntered( const awt::MouseEvent& e )
            {
				if( !mbActive )
					return false;

                mbIsLastPointValid = true;
                maLastPoint.setX( e.X );
                maLastPoint.setY( e.Y );

                return true;
            }

            virtual bool handleMouseExited( const awt::MouseEvent& )
            {
				if( !mbActive )
					return false;

				mbIsLastPointValid = false;
                mbIsLastMouseDownPosValid = false;

                return true;
            }

            virtual bool handleMouseDragged( const awt::MouseEvent& e )
            {
				if( !mbActive )
					return false;

                if (e.Buttons == awt::MouseButton::RIGHT)
                {
                    mbIsLastPointValid = false;
                    return false;
                }

				if(mbIsEraseModeActivated)
                {
					//define the last point as an object
					//we suppose that there's no way this point could be valid
					::basegfx::B2DPolygon aPoly;
                    
                    maLastPoint.setX( e.X-mnSize );
                    maLastPoint.setY( e.Y-mnSize );
                    					
                    aPoly.append( maLastPoint );
                    					
                    maLastPoint.setX( e.X-mnSize );
                    maLastPoint.setY( e.Y+mnSize );
                    
                    aPoly.append( maLastPoint );
                    maLastPoint.setX( e.X+mnSize );
                    maLastPoint.setY( e.Y+mnSize );
                    
                    aPoly.append( maLastPoint );
                    maLastPoint.setX( e.X+mnSize );
                    maLastPoint.setY( e.Y-mnSize );
                    
                    aPoly.append( maLastPoint );
                    maLastPoint.setX( e.X-mnSize );
                    maLastPoint.setY( e.Y-mnSize );
                    
					aPoly.append( maLastPoint );
					
					//now we have defined a Polygon that is closed
					
					//The point is to redraw the LastPoint the way it was originally on the bitmap, 
					//of the slide
        		    for( UnoViewVector::iterator aIter=maViews.begin(), aEnd=maViews.end();
						aIter!=aEnd;
						++aIter )
                    {
						
						//get via SlideImpl instance the bitmap of the slide unmodified to redraw it
						SlideBitmapSharedPtr 		 pBitmap( mrSlide.getCurrentSlideBitmap( (*aIter) ) );
						::cppcanvas::CanvasSharedPtr pCanvas( (*aIter)->getCanvas() );
						
						::basegfx::B2DHomMatrix 	aViewTransform( (*aIter)->getTransformation() );
						const ::basegfx::B2DPoint 		aOutPosPixel( aViewTransform * ::basegfx::B2DPoint() );
						
						// setup a canvas with device coordinate space, the slide
						// bitmap already has the correct dimension.
						::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( pCanvas->clone() );
						
						pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
						
						// render at given output position
						pBitmap->move( aOutPosPixel );
						
                        ::basegfx::B2DPolyPolygon aPolyPoly=::basegfx::B2DPolyPolygon(aPoly);
                        aViewTransform.translate(-aOutPosPixel);
                        aPolyPoly.transform(aViewTransform);
						// set clip so that we just redraw a part of the canvas
						pBitmap->clip(aPolyPoly); 
						pBitmap->draw( pDevicePixelCanvas );
						
						mrScreenUpdater.notifyUpdate(*aIter,true);
					}
					
		        } 
                else 
                {
					if( !mbIsLastPointValid )
					{
						mbIsLastPointValid = true;
						maLastPoint.setX( e.X );
						maLastPoint.setY( e.Y );
					}
					else
					{
						::basegfx::B2DPolygon aPoly;
						aPoly.append( maLastPoint );

						maLastPoint.setX( e.X );
						maLastPoint.setY( e.Y );

						aPoly.append( maLastPoint );

						// paint to all views
						for( UnoViewVector::iterator aIter=maViews.begin(), aEnd=maViews.end();
                             aIter!=aEnd;
                             ++aIter )
						{
							::cppcanvas::PolyPolygonSharedPtr pPolyPoly( 
                                ::cppcanvas::BaseGfxFactory::getInstance().createPolyPolygon( (*aIter)->getCanvas(), 
                                                                                              aPoly ) );
                            
							if( pPolyPoly )
							{
								pPolyPoly->setStrokeWidth(mnStrokeWidth);
                                pPolyPoly->setRGBALineColor( maStrokeColor.getIntegerColor() );
								pPolyPoly->draw();
                                maPolygons.push_back(pPolyPoly);
                            }
						}

						// screen update necessary to show painting
						mrScreenUpdater.notifyUpdate();
					}
				}
                // mouse events captured
                return true;
            }

            virtual bool handleMouseMoved( const awt::MouseEvent& /*e*/ )
            {
                // not used here
                return false; // did not handle the event
            }
			
			
			void update_settings( bool bUserPaintEnabled, RGBColor const& aUserPaintColor, double dUserPaintStrokeWidth )
			{
				maStrokeColor = aUserPaintColor;
				mnStrokeWidth = dUserPaintStrokeWidth;
				mbActive = bUserPaintEnabled;
				if( !mbActive )
					disable();
			}

        private:
            ActivitiesQueue&        mrActivitiesQueue;
            ScreenUpdater&          mrScreenUpdater;
            UnoViewVector           maViews;
            PolyPolygonVector 	    maPolygons;
			RGBColor                maStrokeColor;
            double                  mnStrokeWidth;
            basegfx::B2DPoint       maLastPoint;
            basegfx::B2DPoint       maLastMouseDownPos;
            bool                    mbIsLastPointValid;
            bool                    mbIsLastMouseDownPosValid;
			// added bool for erasing purpose :
			bool					mbIsEraseAllModeActivated;
			bool					mbIsEraseModeActivated;
			Slide&					mrSlide;
            sal_Int32               mnSize;
			bool					mbActive;
        };

        UserPaintOverlaySharedPtr UserPaintOverlay::create( const RGBColor&          rStrokeColor,
                                                            double                   nStrokeWidth,
                                                            const SlideShowContext&  rContext,
                                                            const PolyPolygonVector& rPolygons,
															bool					 bActive )
        {
            UserPaintOverlaySharedPtr pRet( new UserPaintOverlay( rStrokeColor,
                                                                  nStrokeWidth,
                                                                  rContext,
                                                                  rPolygons,
																  bActive));

            return pRet;
        }

        UserPaintOverlay::UserPaintOverlay( const RGBColor&          rStrokeColor,
                                            double                   nStrokeWidth,
                                            const SlideShowContext&  rContext,
                                            const PolyPolygonVector& rPolygons,
											bool					 bActive ) : 
            mpHandler( new PaintOverlayHandler( rStrokeColor, 
                                                nStrokeWidth,
                                                rContext.mrActivitiesQueue,
                                                rContext.mrScreenUpdater,
                                                rContext.mrViewContainer,
                                                //adding a link to Slide
                                                dynamic_cast<Slide&>(rContext.mrCursorManager),
                                                rPolygons, bActive )),
            mrMultiplexer( rContext.mrEventMultiplexer )
        {
            mrMultiplexer.addClickHandler( mpHandler, 3.0 );
            mrMultiplexer.addMouseMoveHandler( mpHandler, 3.0 );
            mrMultiplexer.addViewHandler( mpHandler );
			mrMultiplexer.addUserPaintHandler(mpHandler);
        }
        
        PolyPolygonVector UserPaintOverlay::getPolygons()
        {
            return mpHandler->getPolygons();
        }
                
        void UserPaintOverlay::drawPolygons()
        {
            mpHandler->drawPolygons();
        }
        
		void UserPaintOverlay::update_settings( bool bUserPaintEnabled, RGBColor const& aUserPaintColor, double dUserPaintStrokeWidth )
		{
			mpHandler->update_settings( bUserPaintEnabled, aUserPaintColor, dUserPaintStrokeWidth );
		}


        UserPaintOverlay::~UserPaintOverlay()
        {
            try
            {
                mrMultiplexer.removeMouseMoveHandler( mpHandler );
                mrMultiplexer.removeClickHandler( mpHandler );
                mrMultiplexer.removeViewHandler( mpHandler );
                mpHandler->dispose();
            }
            catch (uno::Exception &) 
            {
                OSL_ENSURE( false, rtl::OUStringToOString(
                                comphelper::anyToString(
                                    cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );
            }
        }
    }
}
