Project import
diff --git a/WEPopover/LICENSE b/WEPopover/LICENSE
new file mode 100755
index 0000000..163d133
--- /dev/null
+++ b/WEPopover/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Werner IT Consultancy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/WEPopover/UIBarButtonItem+WEPopover.h b/WEPopover/UIBarButtonItem+WEPopover.h
new file mode 100755
index 0000000..0b8391a
--- /dev/null
+++ b/WEPopover/UIBarButtonItem+WEPopover.h
@@ -0,0 +1,15 @@
+/*
+ *  UIBarButtonItem+WEPopover.h
+ *  WEPopover
+ *
+ *  Created by Werner Altewischer on 07/05/11.
+ *  Copyright 2010 Werner IT Consultancy. All rights reserved.
+ *
+ */
+
+@interface UIBarButtonItem(WEPopover)
+
+- (CGRect)frameInView:(UIView *)v;
+- (UIView *)superview;
+
+@end
diff --git a/WEPopover/UIBarButtonItem+WEPopover.m b/WEPopover/UIBarButtonItem+WEPopover.m
new file mode 100755
index 0000000..8b33330
--- /dev/null
+++ b/WEPopover/UIBarButtonItem+WEPopover.m
@@ -0,0 +1,52 @@
+/*
+ *  UIBarButtonItem+WEPopover.m
+ *  WEPopover
+ *
+ *  Created by Werner Altewischer on 07/05/11.
+ *  Copyright 2010 Werner IT Consultancy. All rights reserved.
+ *
+ */
+
+#import "UIBarButtonItem+WEPopover.h" 
+
+@implementation UIBarButtonItem(WEPopover)
+
+- (CGRect)frameInView:(UIView *)v {
+	
+	BOOL hasCustomView = (self.customView != nil);
+	
+	if (!hasCustomView) {
+		UIView *tempView = [[UIView alloc] initWithFrame:CGRectZero];
+		self.customView = tempView;
+		[tempView release];	
+	}
+	
+	UIView *parentView = self.customView.superview;
+	NSUInteger indexOfView = [parentView.subviews indexOfObject:self.customView];
+	
+	if (!hasCustomView) {
+		self.customView = nil;
+	}
+	UIView *button = [parentView.subviews objectAtIndex:indexOfView];
+	return [parentView convertRect:button.frame toView:v];
+}
+
+- (UIView *)superview {
+	
+	BOOL hasCustomView = (self.customView != nil);
+	
+	if (!hasCustomView) {
+		UIView *tempView = [[UIView alloc] initWithFrame:CGRectZero];
+		self.customView = tempView;
+		[tempView release];	
+	}
+	
+	UIView *parentView = self.customView.superview;
+	
+	if (!hasCustomView) {
+		self.customView = nil;
+	}
+	return parentView;
+}
+
+@end
diff --git a/WEPopover/WEPopoverContainerView.h b/WEPopover/WEPopoverContainerView.h
new file mode 100755
index 0000000..0aeacd9
--- /dev/null
+++ b/WEPopover/WEPopoverContainerView.h
@@ -0,0 +1,98 @@
+//
+//  WEPopoverContainerView.h
+//  WEPopover
+//
+//  Created by Werner Altewischer on 02/09/10.
+//  Copyright 2010 Werner IT Consultancy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+/**
+ * @brief Properties for the container view determining the area where the actual content view can/may be displayed. Also Images can be supplied for the arrow images and background.
+ */
+@interface WEPopoverContainerViewProperties : NSObject
+{
+	NSString *bgImageName;
+	NSString *upArrowImageName;
+	NSString *downArrowImageName;
+	NSString *leftArrowImageName;
+	NSString *rightArrowImageName;
+	CGFloat leftBgMargin;
+	CGFloat rightBgMargin;
+	CGFloat topBgMargin;
+	CGFloat bottomBgMargin;
+	NSInteger topBgCapSize;
+	NSInteger leftBgCapSize;
+	CGFloat arrowMargin;
+}
+
+@property(nonatomic, retain) NSString *bgImageName;
+@property(nonatomic, retain) NSString *upArrowImageName;
+@property(nonatomic, retain) NSString *downArrowImageName;
+@property(nonatomic, retain) NSString *leftArrowImageName;
+@property(nonatomic, retain) NSString *rightArrowImageName;
+@property(nonatomic, assign) CGFloat leftBgMargin;
+@property(nonatomic, assign) CGFloat rightBgMargin;
+@property(nonatomic, assign) CGFloat topBgMargin;
+@property(nonatomic, assign) CGFloat bottomBgMargin;
+@property(nonatomic, assign) CGFloat leftContentMargin;
+@property(nonatomic, assign) CGFloat rightContentMargin;
+@property(nonatomic, assign) CGFloat topContentMargin;
+@property(nonatomic, assign) CGFloat bottomContentMargin;
+@property(nonatomic, assign) NSInteger topBgCapSize;
+@property(nonatomic, assign) NSInteger leftBgCapSize;
+@property(nonatomic, assign) CGFloat arrowMargin;
+
+@end
+
+@class WEPopoverContainerView;
+
+/**
+ * @brief Container/background view for displaying a popover view.
+ */
+@interface WEPopoverContainerView : UIView {
+	UIImage *bgImage;
+	UIImage *arrowImage;
+	
+	WEPopoverContainerViewProperties *properties;
+	
+	UIPopoverArrowDirection arrowDirection;
+	
+	CGRect arrowRect;
+	CGRect bgRect;
+	CGPoint offset;
+	CGPoint arrowOffset;
+	
+	CGSize correctedSize;
+	UIView *contentView;
+}
+
+/**
+ * @brief The current arrow direction for the popover.
+ */
+@property (nonatomic, readonly) UIPopoverArrowDirection arrowDirection;
+
+/**
+ * @brief The content view being displayed.
+ */
+@property (nonatomic, retain) UIView *contentView;
+
+/**
+ * @brief Initializes the position of the popover with a size, anchor rect, display area and permitted arrow directions and optionally the properties. 
+ * If the last is not supplied the defaults are taken (requires images to be present in bundle representing a black rounded background with partial transparency).
+ */
+- (id)initWithSize:(CGSize)theSize 
+		anchorRect:(CGRect)anchorRect 
+	   displayArea:(CGRect)displayArea
+permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections
+		properties:(WEPopoverContainerViewProperties *)properties;	
+
+/**
+ * @brief To update the position of the popover with a new anchor rect, display area and permitted arrow directions
+ */
+- (void)updatePositionWithAnchorRect:(CGRect)anchorRect 
+						 displayArea:(CGRect)displayArea
+			permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections;	
+
+@end
diff --git a/WEPopover/WEPopoverContainerView.m b/WEPopover/WEPopoverContainerView.m
new file mode 100755
index 0000000..9980031
--- /dev/null
+++ b/WEPopover/WEPopoverContainerView.m
@@ -0,0 +1,371 @@
+//
+//  WEPopoverContainerViewProperties.m
+//  WEPopover
+//
+//  Created by Werner Altewischer on 02/09/10.
+//  Copyright 2010 Werner IT Consultancy. All rights reserved.
+//
+
+#import "WEPopoverContainerView.h"
+
+@implementation WEPopoverContainerViewProperties
+
+@synthesize bgImageName, upArrowImageName, downArrowImageName, leftArrowImageName, rightArrowImageName, topBgMargin, bottomBgMargin, leftBgMargin, rightBgMargin, topBgCapSize, leftBgCapSize;
+@synthesize leftContentMargin, rightContentMargin, topContentMargin, bottomContentMargin, arrowMargin;
+
+- (void)dealloc {
+	self.bgImageName = nil;
+	self.upArrowImageName = nil;
+	self.downArrowImageName = nil;
+	self.leftArrowImageName = nil;
+	self.rightArrowImageName = nil;
+	[super dealloc];
+}
+
+@end
+
+@interface WEPopoverContainerView(Private)
+
+- (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect displayArea:(CGRect)displayArea permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections;
+- (CGRect)contentRect;
+- (CGSize)contentSize;
+- (void)setProperties:(WEPopoverContainerViewProperties *)props;
+- (void)initFrame;
+
+@end
+
+@implementation WEPopoverContainerView
+
+@synthesize arrowDirection, contentView;
+
+- (id)initWithSize:(CGSize)theSize 
+		anchorRect:(CGRect)anchorRect 
+	   displayArea:(CGRect)displayArea
+permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections
+		properties:(WEPopoverContainerViewProperties *)theProperties {
+	if ((self = [super initWithFrame:CGRectZero])) {
+		
+		[self setProperties:theProperties];
+		correctedSize = CGSizeMake(theSize.width + properties.leftBgMargin + properties.rightBgMargin + properties.leftContentMargin + properties.rightContentMargin, 
+								   theSize.height + properties.topBgMargin + properties.bottomBgMargin + properties.topContentMargin + properties.bottomContentMargin);	
+		[self determineGeometryForSize:correctedSize anchorRect:anchorRect displayArea:displayArea permittedArrowDirections:permittedArrowDirections];
+		[self initFrame];
+		self.backgroundColor = [UIColor clearColor];
+		UIImage *theImage = [UIImage imageNamed:properties.bgImageName];
+		bgImage = [[theImage stretchableImageWithLeftCapWidth:properties.leftBgCapSize topCapHeight:properties.topBgCapSize] retain];
+		
+		self.clipsToBounds = YES;
+		self.userInteractionEnabled = YES;
+		
+		self.layer.shadowOffset = CGSizeMake(3, 3);
+		self.layer.shadowRadius = 6;
+		self.layer.shadowOpacity = 0.3;
+		self.clipsToBounds = NO;
+	}
+	return self;
+}
+
+- (void)dealloc {
+	[properties release];
+	[contentView release];
+	[bgImage release];
+	[arrowImage release];
+	[super dealloc];
+}
+
+- (void)drawRect:(CGRect)rect {
+	[bgImage drawInRect:bgRect blendMode:kCGBlendModeNormal alpha:1.0];
+	[arrowImage drawInRect:arrowRect blendMode:kCGBlendModeNormal alpha:1.0]; 
+}
+
+- (void)updatePositionWithAnchorRect:(CGRect)anchorRect 
+						 displayArea:(CGRect)displayArea
+			permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections {
+	[self determineGeometryForSize:correctedSize anchorRect:anchorRect displayArea:displayArea permittedArrowDirections:permittedArrowDirections];
+	[self initFrame];
+}
+
+- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
+	return CGRectContainsPoint(self.contentRect, point);	
+} 
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+	
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
+	
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
+	
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+	
+}
+
+- (void)setContentView:(UIView *)v {
+	if (v != contentView) {
+		[contentView release];
+		contentView = [v retain];		
+		contentView.frame = self.contentRect;		
+		[self addSubview:contentView];
+	}
+}
+
+
+
+@end
+
+@implementation WEPopoverContainerView(Private)
+
+- (void)initFrame {
+	CGRect theFrame = CGRectOffset(CGRectUnion(bgRect, arrowRect), offset.x, offset.y);
+	
+	//If arrow rect origin is < 0 the frame above is extended to include it so we should offset the other rects
+	arrowOffset = CGPointMake(MAX(0, -arrowRect.origin.x), MAX(0, -arrowRect.origin.y));
+	bgRect = CGRectOffset(bgRect, arrowOffset.x, arrowOffset.y);
+	arrowRect = CGRectOffset(arrowRect, arrowOffset.x, arrowOffset.y);
+	
+	self.frame = theFrame;	
+}																		 
+
+- (CGSize)contentSize {
+	return self.contentRect.size;
+}
+
+- (CGRect)contentRect {
+	CGRect rect = CGRectMake(properties.leftBgMargin + properties.leftContentMargin + arrowOffset.x, 
+							 properties.topBgMargin + properties.topContentMargin + arrowOffset.y, 
+							 bgRect.size.width - properties.leftBgMargin - properties.rightBgMargin - properties.leftContentMargin - properties.rightContentMargin,
+							 bgRect.size.height - properties.topBgMargin - properties.bottomBgMargin - properties.topContentMargin - properties.bottomContentMargin);
+	return rect;
+}
+
+- (void)setProperties:(WEPopoverContainerViewProperties *)props {
+	if (properties != props) {
+		[properties release];
+		properties = [props retain];
+	}
+}
+
+- (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect displayArea:(CGRect)displayArea permittedArrowDirections:(UIPopoverArrowDirection)supportedArrowDirections {	
+	
+	//Determine the frame, it should not go outside the display area
+	UIPopoverArrowDirection theArrowDirection = UIPopoverArrowDirectionUp;
+	
+	offset =  CGPointZero;
+	bgRect = CGRectZero;
+	arrowRect = CGRectZero;
+	arrowDirection = UIPopoverArrowDirectionUnknown;
+	
+	CGFloat biggestSurface = -FLT_MAX;
+	CGFloat currentMinMargin = -FLT_MAX;
+	
+	UIImage *upArrowImage = [UIImage imageNamed:properties.upArrowImageName];
+	UIImage *downArrowImage = [UIImage imageNamed:properties.downArrowImageName];
+	UIImage *leftArrowImage = [UIImage imageNamed:properties.leftArrowImageName];
+	UIImage *rightArrowImage = [UIImage imageNamed:properties.rightArrowImageName];
+	
+	while (theArrowDirection <= UIPopoverArrowDirectionRight) {
+		
+		if ((supportedArrowDirections & theArrowDirection)) {
+			
+			CGRect theBgRect = CGRectZero;
+			CGRect theArrowRect = CGRectZero;
+			CGPoint theOffset = CGPointZero;
+			CGFloat xArrowOffset = 0.0;
+			CGFloat yArrowOffset = 0.0;
+			CGPoint anchorPoint = CGPointZero;
+			
+			switch (theArrowDirection) {
+				case UIPopoverArrowDirectionUp:
+					
+					anchorPoint = CGPointMake(CGRectGetMidX(anchorRect), CGRectGetMaxY(anchorRect));
+					
+					xArrowOffset = theSize.width / 2 - upArrowImage.size.width / 2;
+					yArrowOffset = properties.topBgMargin - upArrowImage.size.height;
+					
+					theOffset = CGPointMake(anchorPoint.x - xArrowOffset - upArrowImage.size.width / 2, anchorPoint.y  - yArrowOffset);
+					theBgRect = CGRectMake(0, 0, theSize.width, theSize.height);
+					
+					if (theOffset.x < 0) {
+						xArrowOffset += theOffset.x;
+						theOffset.x = 0;
+					} else if (theOffset.x + theSize.width > displayArea.size.width) {
+						xArrowOffset += (theOffset.x + theSize.width - displayArea.size.width);
+						theOffset.x = displayArea.size.width - theSize.width;
+					}
+					
+					//Cap the arrow offset
+					xArrowOffset = MAX(xArrowOffset, properties.leftBgMargin + properties.arrowMargin);
+					xArrowOffset = MIN(xArrowOffset, theSize.width - properties.rightBgMargin - properties.arrowMargin - upArrowImage.size.width);
+					
+					theArrowRect = CGRectMake(xArrowOffset, yArrowOffset, upArrowImage.size.width, upArrowImage.size.height);
+					
+					break;
+				case UIPopoverArrowDirectionDown:
+					
+					anchorPoint = CGPointMake(CGRectGetMidX(anchorRect), CGRectGetMinY(anchorRect));
+					
+					xArrowOffset = theSize.width / 2 - downArrowImage.size.width / 2;
+					yArrowOffset = theSize.height - properties.bottomBgMargin;
+					
+					theOffset = CGPointMake(anchorPoint.x - xArrowOffset - downArrowImage.size.width / 2, anchorPoint.y - yArrowOffset - downArrowImage.size.height);
+					theBgRect = CGRectMake(0, 0, theSize.width, theSize.height);
+					
+					if (theOffset.x < 0) {
+						xArrowOffset += theOffset.x;
+						theOffset.x = 0;
+					} else if (theOffset.x + theSize.width > displayArea.size.width) {
+						xArrowOffset += (theOffset.x + theSize.width - displayArea.size.width);
+						theOffset.x = displayArea.size.width - theSize.width;
+					}
+					
+					//Cap the arrow offset
+					xArrowOffset = MAX(xArrowOffset, properties.leftBgMargin + properties.arrowMargin);
+					xArrowOffset = MIN(xArrowOffset, theSize.width - properties.rightBgMargin - properties.arrowMargin - downArrowImage.size.width);
+					
+					theArrowRect = CGRectMake(xArrowOffset , yArrowOffset, downArrowImage.size.width, downArrowImage.size.height);
+					
+					break;
+				case UIPopoverArrowDirectionLeft:
+					
+					anchorPoint = CGPointMake(CGRectGetMaxX(anchorRect), CGRectGetMidY(anchorRect));
+					
+					xArrowOffset = properties.leftBgMargin - leftArrowImage.size.width;
+					yArrowOffset = theSize.height / 2  - leftArrowImage.size.height / 2;
+					
+					theOffset = CGPointMake(anchorPoint.x - xArrowOffset, anchorPoint.y - yArrowOffset - leftArrowImage.size.height / 2);
+					theBgRect = CGRectMake(0, 0, theSize.width, theSize.height);
+					
+					if (theOffset.y < 0) {
+						yArrowOffset += theOffset.y;
+						theOffset.y = 0;
+					} else if (theOffset.y + theSize.height > displayArea.size.height) {
+						yArrowOffset += (theOffset.y + theSize.height - displayArea.size.height);
+						theOffset.y = displayArea.size.height - theSize.height;
+					}
+					
+					//Cap the arrow offset
+					yArrowOffset = MAX(yArrowOffset, properties.topBgMargin + properties.arrowMargin);
+					yArrowOffset = MIN(yArrowOffset, theSize.height - properties.bottomBgMargin - properties.arrowMargin - leftArrowImage.size.height);
+					
+					theArrowRect = CGRectMake(xArrowOffset, yArrowOffset, leftArrowImage.size.width, leftArrowImage.size.height);
+					
+					break;
+				case UIPopoverArrowDirectionRight:
+					
+					anchorPoint = CGPointMake(CGRectGetMinX(anchorRect), CGRectGetMidY(anchorRect));
+					
+					xArrowOffset = theSize.width - properties.rightBgMargin;
+					yArrowOffset = theSize.height / 2  - rightArrowImage.size.width / 2;
+					
+					theOffset = CGPointMake(anchorPoint.x - xArrowOffset - rightArrowImage.size.width, anchorPoint.y - yArrowOffset - rightArrowImage.size.height / 2);
+					theBgRect = CGRectMake(0, 0, theSize.width, theSize.height);
+					
+					if (theOffset.y < 0) {
+						yArrowOffset += theOffset.y;
+						theOffset.y = 0;
+					} else if (theOffset.y + theSize.height > displayArea.size.height) {
+						yArrowOffset += (theOffset.y + theSize.height - displayArea.size.height);
+						theOffset.y = displayArea.size.height - theSize.height;
+					}
+					
+					//Cap the arrow offset
+					yArrowOffset = MAX(yArrowOffset, properties.topBgMargin + properties.arrowMargin);
+					yArrowOffset = MIN(yArrowOffset, theSize.height - properties.bottomBgMargin - properties.arrowMargin - rightArrowImage.size.height);
+					
+					theArrowRect = CGRectMake(xArrowOffset, yArrowOffset, rightArrowImage.size.width, rightArrowImage.size.height);
+					
+					break;
+			}
+			
+			CGRect bgFrame = CGRectOffset(theBgRect, theOffset.x, theOffset.y);
+			
+			CGFloat minMarginLeft = CGRectGetMinX(bgFrame) - CGRectGetMinX(displayArea);
+			CGFloat minMarginRight = CGRectGetMaxX(displayArea) - CGRectGetMaxX(bgFrame); 
+			CGFloat minMarginTop = CGRectGetMinY(bgFrame) - CGRectGetMinY(displayArea); 
+			CGFloat minMarginBottom = CGRectGetMaxY(displayArea) - CGRectGetMaxY(bgFrame); 
+			
+			if (minMarginLeft < 0) {
+			    // Popover is too wide and clipped on the left; decrease width
+			    // and move it to the right
+			    theOffset.x -= minMarginLeft;
+			    theBgRect.size.width += minMarginLeft;
+			    minMarginLeft = 0;
+			    if (theArrowDirection == UIPopoverArrowDirectionRight) {
+			        theArrowRect.origin.x = CGRectGetMaxX(theBgRect) - properties.rightBgMargin;
+			    }
+			}
+			if (minMarginRight < 0) {
+			    // Popover is too wide and clipped on the right; move to the left
+				theOffset.x += minMarginRight;
+				
+			    if (theArrowDirection == UIPopoverArrowDirectionLeft) {
+			        theArrowRect.origin.x = CGRectGetMinX(theBgRect) - leftArrowImage.size.width + properties.leftBgMargin;
+			    } else {
+					theArrowRect.origin.x -= minMarginRight;
+				}
+
+				minMarginRight = 0;
+			}
+			if (minMarginTop < 0) {
+			    // Popover is too high and clipped at the top; decrease height
+			    // and move it down
+			    theOffset.y -= minMarginTop;
+			    theBgRect.size.height += minMarginTop;
+			    minMarginTop = 0;
+			    if (theArrowDirection == UIPopoverArrowDirectionDown) {
+			        theArrowRect.origin.y = CGRectGetMaxY(theBgRect) - properties.bottomBgMargin;
+			    }
+			}
+			if (minMarginBottom < 0) {
+			    // Popover is too high and clipped at the bottom; decrease height.
+			    theBgRect.size.height += minMarginBottom;
+			    minMarginBottom = 0;
+			    if (theArrowDirection == UIPopoverArrowDirectionUp) {
+			        theArrowRect.origin.y = CGRectGetMinY(theBgRect) - upArrowImage.size.height + properties.topBgMargin;
+			    }
+			}
+			bgFrame = CGRectOffset(theBgRect, theOffset.x, theOffset.y);
+            
+			CGFloat minMargin = MIN(minMarginLeft, minMarginRight);
+			minMargin = MIN(minMargin, minMarginTop);
+			minMargin = MIN(minMargin, minMarginBottom);
+			
+			// Calculate intersection and surface
+			CGRect intersection = CGRectIntersection(displayArea, bgFrame);
+			CGFloat surface = intersection.size.width * intersection.size.height;
+			
+			if (surface >= biggestSurface && minMargin >= currentMinMargin) {
+				biggestSurface = surface;
+				offset = theOffset;
+				arrowRect = theArrowRect;
+				bgRect = theBgRect;
+				arrowDirection = theArrowDirection;
+				currentMinMargin = minMargin;
+			}
+		}
+		
+		theArrowDirection <<= 1;
+	}
+	
+	switch (arrowDirection) {
+		case UIPopoverArrowDirectionUp:
+			arrowImage = [upArrowImage retain];
+			break;
+		case UIPopoverArrowDirectionDown:
+			arrowImage = [downArrowImage retain];
+			break;
+		case UIPopoverArrowDirectionLeft:
+			arrowImage = [leftArrowImage retain];
+			break;
+		case UIPopoverArrowDirectionRight:
+			arrowImage = [rightArrowImage retain];
+			break;
+	}
+}
+
+@end
\ No newline at end of file
diff --git a/WEPopover/WEPopoverController.h b/WEPopover/WEPopoverController.h
new file mode 100755
index 0000000..324c869
--- /dev/null
+++ b/WEPopover/WEPopoverController.h
@@ -0,0 +1,67 @@
+//
+//  WEPopoverController.h
+//  WEPopover
+//
+//  Created by Werner Altewischer on 02/09/10.
+//  Copyright 2010 Werner IT Consultancy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "WEPopoverContainerView.h"
+#import "WETouchableView.h"
+
+@class WEPopoverController;
+
+@protocol WEPopoverControllerDelegate<NSObject>
+
+- (void)popoverControllerDidDismissPopover:(WEPopoverController *)popoverController;
+- (BOOL)popoverControllerShouldDismissPopover:(WEPopoverController *)popoverController;
+
+@end
+
+/**
+ * @brief Popover controller for the iPhone, mimicing the iPad UIPopoverController interface. See that class for more details.
+ */
+@interface WEPopoverController : NSObject<WETouchableViewDelegate> {
+	UIViewController *contentViewController;
+	UIView *view;
+	WETouchableView *backgroundView;
+	
+	BOOL popoverVisible;
+	UIPopoverArrowDirection popoverArrowDirection;
+	id <WEPopoverControllerDelegate> delegate;
+	CGSize popoverContentSize;
+	WEPopoverContainerViewProperties *containerViewProperties;
+	id <NSObject> context;
+	NSArray *passthroughViews;	
+}
+
+@property(nonatomic, retain) UIViewController *contentViewController;
+
+@property (nonatomic, readonly) UIView *view;
+@property (nonatomic, readonly, getter=isPopoverVisible) BOOL popoverVisible;
+@property (nonatomic, readonly) UIPopoverArrowDirection popoverArrowDirection;
+@property (nonatomic, assign) id <WEPopoverControllerDelegate> delegate;
+@property (nonatomic, assign) CGSize popoverContentSize;
+@property (nonatomic, retain) WEPopoverContainerViewProperties *containerViewProperties;
+@property (nonatomic, retain) id <NSObject> context;
+@property (nonatomic, copy) NSArray *passthroughViews;
+
+- (id)initWithContentViewController:(UIViewController *)theContentViewController;
+
+- (void)dismissPopoverAnimated:(BOOL)animated;
+
+- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item 
+			   permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections 
+							   animated:(BOOL)animated;
+
+- (void)presentPopoverFromRect:(CGRect)rect 
+						inView:(UIView *)view 
+	  permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections 
+					  animated:(BOOL)animated;
+
+- (void)repositionPopoverFromRect:(CGRect)rect
+						   inView:(UIView *)view
+		 permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections;
+
+@end
diff --git a/WEPopover/WEPopoverController.m b/WEPopover/WEPopoverController.m
new file mode 100755
index 0000000..d749fed
--- /dev/null
+++ b/WEPopover/WEPopoverController.m
@@ -0,0 +1,288 @@
+//
+//  WEPopoverController.m
+//  WEPopover
+//
+//  Created by Werner Altewischer on 02/09/10.
+//  Copyright 2010 Werner IT Consultancy. All rights reserved.
+//
+
+#import "WEPopoverController.h"
+#import "WEPopoverParentView.h"
+#import "UIBarButtonItem+WEPopover.h"
+
+#define FADE_DURATION 0.3
+
+@interface WEPopoverController(Private)
+
+- (UIView *)keyView;
+- (void)updateBackgroundPassthroughViews;
+- (void)setView:(UIView *)v;
+- (CGRect)displayAreaForView:(UIView *)theView;
+- (WEPopoverContainerViewProperties *)defaultContainerViewProperties;
+- (void)dismissPopoverAnimated:(BOOL)animated userInitiated:(BOOL)userInitiated;
+
+@end
+
+
+@implementation WEPopoverController
+
+@synthesize contentViewController;
+@synthesize popoverContentSize;
+@synthesize popoverVisible;
+@synthesize popoverArrowDirection;
+@synthesize delegate;
+@synthesize view;
+@synthesize containerViewProperties;
+@synthesize context;
+@synthesize passthroughViews;
+
+- (id)init {
+	if ((self = [super init])) {
+	}
+	return self;
+}
+
+- (id)initWithContentViewController:(UIViewController *)viewController {
+	if ((self = [self init])) {
+		self.contentViewController = viewController;
+	}
+	return self;
+}
+
+- (void)dealloc {
+	[self dismissPopoverAnimated:NO];
+	[contentViewController release];
+	[containerViewProperties release];
+	[passthroughViews release];
+	self.context = nil;
+	[super dealloc];
+}
+
+- (void)setContentViewController:(UIViewController *)vc {
+	if (vc != contentViewController) {
+		[contentViewController release];
+		contentViewController = [vc retain];
+		popoverContentSize = CGSizeZero;
+	}
+}
+
+//Overridden setter to copy the passthroughViews to the background view if it exists already
+- (void)setPassthroughViews:(NSArray *)array {
+	[passthroughViews release];
+	passthroughViews = nil;
+	if (array) {
+		passthroughViews = [[NSArray alloc] initWithArray:array];
+	}
+	[self updateBackgroundPassthroughViews];
+}
+
+- (void)dismissPopoverAnimated:(BOOL)animated {
+	
+	[self dismissPopoverAnimated:animated userInitiated:NO];
+}
+
+- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item 
+			   permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections 
+							   animated:(BOOL)animated {
+	
+	UIView *v = [self keyView];
+	CGRect rect = [item frameInView:v];
+	
+	return [self presentPopoverFromRect:rect inView:v permittedArrowDirections:arrowDirections animated:animated];
+}
+
+- (void)presentPopoverFromRect:(CGRect)rect 
+						inView:(UIView *)theView 
+	  permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections 
+					  animated:(BOOL)animated {
+	
+	
+	[self dismissPopoverAnimated:NO];
+	
+	//First force a load view for the contentViewController so the popoverContentSize is properly initialized
+	// NEST: edit to avoid warning
+	if (contentViewController.view == nil) return;
+	
+	if (CGSizeEqualToSize(popoverContentSize, CGSizeZero)) {
+		popoverContentSize = contentViewController.contentSizeForViewInPopover;
+	}
+	
+	CGRect displayArea = [self displayAreaForView:theView];
+	
+	WEPopoverContainerViewProperties *props = self.containerViewProperties ? self.containerViewProperties : [self defaultContainerViewProperties];
+	WEPopoverContainerView *containerView = [[[WEPopoverContainerView alloc] initWithSize:self.popoverContentSize anchorRect:rect displayArea:displayArea permittedArrowDirections:arrowDirections properties:props] autorelease];
+	popoverArrowDirection = containerView.arrowDirection;
+	
+	UIView *keyView = self.keyView;
+	
+	backgroundView = [[WETouchableView alloc] initWithFrame:keyView.bounds];
+	backgroundView.contentMode = UIViewContentModeScaleToFill;
+	backgroundView.autoresizingMask = ( UIViewAutoresizingFlexibleLeftMargin |
+									   UIViewAutoresizingFlexibleWidth |
+									   UIViewAutoresizingFlexibleRightMargin |
+									   UIViewAutoresizingFlexibleTopMargin |
+									   UIViewAutoresizingFlexibleHeight |
+									   UIViewAutoresizingFlexibleBottomMargin);
+	backgroundView.backgroundColor = [UIColor clearColor];
+	backgroundView.delegate = self;
+	
+	[keyView addSubview:backgroundView];
+	
+	containerView.frame = [theView convertRect:containerView.frame toView:backgroundView];
+	
+	[backgroundView addSubview:containerView];
+	
+	containerView.contentView = contentViewController.view;
+	containerView.autoresizingMask = ( UIViewAutoresizingFlexibleLeftMargin |
+									  UIViewAutoresizingFlexibleRightMargin);
+	
+	self.view = containerView;
+	[self updateBackgroundPassthroughViews];
+	
+	[contentViewController viewWillAppear:animated];
+	
+	[self.view becomeFirstResponder];
+	
+	if (animated) {
+		self.view.alpha = 0.0;
+
+		[UIView animateWithDuration:FADE_DURATION animations:^{
+			self.view.alpha = 1.0;
+		} completion:^(BOOL finished) {
+			self.view.userInteractionEnabled = YES;
+			popoverVisible = YES;
+			[contentViewController viewDidAppear:YES];
+		}];
+	} else {
+		popoverVisible = YES;
+		[contentViewController viewDidAppear:animated];
+	}	
+}
+
+- (void)repositionPopoverFromRect:(CGRect)rect
+						   inView:(UIView *)theView
+		 permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections {
+	
+	CGRect displayArea = [self displayAreaForView:theView];
+	WEPopoverContainerView *containerView = (WEPopoverContainerView *)self.view;
+	[containerView updatePositionWithAnchorRect:rect
+									displayArea:displayArea
+					   permittedArrowDirections:arrowDirections];
+	
+	popoverArrowDirection = containerView.arrowDirection;
+	containerView.frame = [theView convertRect:containerView.frame toView:backgroundView];
+}
+
+#pragma mark -
+#pragma mark WETouchableViewDelegate implementation
+
+- (void)viewWasTouched:(WETouchableView *)view {
+	if (popoverVisible) {
+		if (!delegate || [delegate popoverControllerShouldDismissPopover:self]) {
+			[self dismissPopoverAnimated:YES userInitiated:YES];
+		}
+	}
+}
+
+@end
+
+
+@implementation WEPopoverController(Private)
+
+- (UIView *)keyView {
+	UIWindow *w = [[UIApplication sharedApplication] keyWindow];
+	if (w.subviews.count > 0) {
+		return [w.subviews objectAtIndex:0];
+	} else {
+		return w;
+	}
+}
+
+- (void)setView:(UIView *)v {
+	if (view != v) {
+		[view release];
+		view = [v retain];
+	}
+}
+
+- (void)updateBackgroundPassthroughViews {
+	backgroundView.passthroughViews = passthroughViews;
+}
+
+
+- (void)dismissPopoverAnimated:(BOOL)animated userInitiated:(BOOL)userInitiated {
+	if (self.view) {
+		[contentViewController viewWillDisappear:animated];
+		popoverVisible = NO;
+		[self.view resignFirstResponder];
+		if (animated) {
+			
+			self.view.userInteractionEnabled = NO;
+			[UIView animateWithDuration:FADE_DURATION animations:^{
+				self.view.alpha = 0.0;
+			} completion:^(BOOL finished) {
+				popoverVisible = NO;
+				[contentViewController viewDidDisappear:YES];
+				[self.view removeFromSuperview];
+				self.view = nil;
+				[backgroundView removeFromSuperview];
+				[backgroundView release];
+				backgroundView = nil;
+								
+				if (userInitiated) {
+					//Only send message to delegate in case the user initiated this event, which is if he touched outside the view
+					[delegate popoverControllerDidDismissPopover:self];
+				}
+			}];
+		} else {
+			[contentViewController viewDidDisappear:animated];
+			[self.view removeFromSuperview];
+			self.view = nil;
+			[backgroundView removeFromSuperview];
+			[backgroundView release];
+			backgroundView = nil;
+		}
+	}
+}
+
+- (CGRect)displayAreaForView:(UIView *)theView {
+	CGRect displayArea = CGRectZero;
+	if ([theView conformsToProtocol:@protocol(WEPopoverParentView)] && [theView respondsToSelector:@selector(displayAreaForPopover)]) {
+		displayArea = [(id <WEPopoverParentView>)theView displayAreaForPopover];
+	} else {
+		displayArea = [[[UIApplication sharedApplication] keyWindow] convertRect:[[UIScreen mainScreen] applicationFrame] toView:theView];
+		displayArea = CGRectInset(displayArea, 6, 6);	// give some margin from the edges of the screen
+	}
+	return displayArea;
+}
+
+//Enable to use the simple popover style
+- (WEPopoverContainerViewProperties *)defaultContainerViewProperties {
+	WEPopoverContainerViewProperties *ret = [[WEPopoverContainerViewProperties new] autorelease];
+	
+	CGSize imageSize = CGSizeMake(30.0f, 30.0f);
+	NSString *bgImageName = @"popoverBgSimple.png";
+	CGFloat bgMargin = 0.0;
+	CGFloat contentMargin = 12.0;
+	
+	ret.leftBgMargin = bgMargin;
+	ret.rightBgMargin = bgMargin;
+	ret.topBgMargin = bgMargin;
+	ret.bottomBgMargin = bgMargin;
+	ret.leftBgCapSize = imageSize.width/2;
+	ret.topBgCapSize = imageSize.height/2;
+	ret.bgImageName = bgImageName;
+	ret.leftContentMargin = contentMargin;
+	ret.rightContentMargin = contentMargin;
+	ret.topContentMargin = contentMargin;
+	ret.bottomContentMargin = contentMargin;
+	ret.arrowMargin = 1.0;
+	
+	ret.upArrowImageName = @"popoverArrowUpSimple.png";
+	ret.downArrowImageName = @"popoverArrowDownSimple.png";
+	ret.leftArrowImageName = @"popoverArrowLeftSimple.png";
+	ret.rightArrowImageName = @"popoverArrowRightSimple.png";
+	return ret;
+}
+
+@end
diff --git a/WEPopover/WEPopoverParentView.h b/WEPopover/WEPopoverParentView.h
new file mode 100755
index 0000000..111f8fa
--- /dev/null
+++ b/WEPopover/WEPopoverParentView.h
@@ -0,0 +1,15 @@
+/*
+ *  WEPopoverParentView.h
+ *  WEPopover
+ *
+ *  Created by Werner Altewischer on 02/09/10.
+ *  Copyright 2010 Werner IT Consultancy. All rights reserved.
+ *
+ */
+
+@protocol WEPopoverParentView
+
+@optional
+- (CGRect)displayAreaForPopover;
+
+@end
\ No newline at end of file
diff --git a/WEPopover/WETouchableView.h b/WEPopover/WETouchableView.h
new file mode 100755
index 0000000..b260812
--- /dev/null
+++ b/WEPopover/WETouchableView.h
@@ -0,0 +1,36 @@
+//
+//  WETouchableView.h
+//  WEPopover
+//
+//  Created by Werner Altewischer on 12/21/10.
+//  Copyright 2010 Werner IT Consultancy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class WETouchableView;
+
+/**
+  * @brief delegate to receive touch events
+  */
+@protocol WETouchableViewDelegate<NSObject>
+
+- (void)viewWasTouched:(WETouchableView *)view;
+
+@end
+
+/**
+ * @brief View that can handle touch events and/or disable touch forwording to child views
+ */
+@interface WETouchableView : UIView {
+	BOOL touchForwardingDisabled;
+	id <WETouchableViewDelegate> delegate;
+	NSArray *passthroughViews;
+	BOOL testHits;
+}
+
+@property (nonatomic, assign) BOOL touchForwardingDisabled;
+@property (nonatomic, assign) id <WETouchableViewDelegate> delegate;
+@property (nonatomic, copy) NSArray *passthroughViews;
+
+@end
diff --git a/WEPopover/WETouchableView.m b/WEPopover/WETouchableView.m
new file mode 100755
index 0000000..e04fc9d
--- /dev/null
+++ b/WEPopover/WETouchableView.m
@@ -0,0 +1,70 @@
+//
+//  WETouchableView.m
+//  WEPopover
+//
+//  Created by Werner Altewischer on 12/21/10.
+//  Copyright 2010 Werner IT Consultancy. All rights reserved.
+//
+
+#import "WETouchableView.h"
+
+@interface WETouchableView(Private)
+
+- (BOOL)isPassthroughView:(UIView *)v;
+
+@end
+
+@implementation WETouchableView
+
+@synthesize touchForwardingDisabled, delegate, passthroughViews;
+
+- (void)dealloc {
+	[passthroughViews release];
+	[super dealloc];
+}
+
+- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
+	if (testHits) {
+		return nil;
+	} else if (touchForwardingDisabled) {
+		return self;
+	} else {
+		UIView *hitView = [super hitTest:point withEvent:event];
+		
+		if (hitView == self) {
+			//Test whether any of the passthrough views would handle this touch
+			testHits = YES;
+			UIView *superHitView = [self.superview hitTest:point withEvent:event];
+			testHits = NO;
+			
+			if ([self isPassthroughView:superHitView]) {
+				hitView = superHitView;
+			}
+		}
+		
+		return hitView;
+	}
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+	[self.delegate viewWasTouched:self];
+}
+
+@end
+
+@implementation WETouchableView(Private)
+
+- (BOOL)isPassthroughView:(UIView *)v {
+	
+	if (v == nil) {
+		return NO;
+	}
+	
+	if ([passthroughViews containsObject:v]) {
+		return YES;
+	}
+	
+	return [self isPassthroughView:v.superview];
+}
+
+@end