diff --git a/include/ajax.config.php b/include/ajax.config.php
index 7dcfd9972717e9c8cd5cb14a217b0e3b361dd9ee..fc9fb2c3fc8622108054052828b7e6bb9a42dcd6 100644
--- a/include/ajax.config.php
+++ b/include/ajax.config.php
@@ -19,7 +19,7 @@ if(!defined('INCLUDE_DIR')) die('!');
 class ConfigAjaxAPI extends AjaxController {
 
     //config info UI might need.
-    function ui() {
+    function scp_ui() {
         global $thisstaff, $cfg;
 
         $config=array('ticket_lock_time'=>($cfg->getLockTime()*3600),
diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index 458e430ea83192703bea52c026413af63c4edb63..648edc8256939ef0c3131e57684a73516a5d7d78 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -20,11 +20,11 @@ include_once(INCLUDE_DIR.'class.ticket.php');
 
 class TicketsAjaxAPI extends AjaxController {
    
-    function search() {
+    function lookup() {
         global $thisstaff;
 
         if(!is_numeric($_REQUEST['q']))
-            return self::searchByEmail();
+            return self::lookupByEmail();
 
 
         $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25;
@@ -53,7 +53,7 @@ class TicketsAjaxAPI extends AjaxController {
         return $this->json_encode($tickets);
     }
 
-    function searchByEmail() {
+    function lookupByEmail() {
         global $thisstaff;
 
 
@@ -84,6 +84,51 @@ class TicketsAjaxAPI extends AjaxController {
         return $this->json_encode($tickets);
     }
 
+    function search() {
+        global $thisstaff;
+          
+        $result=array();
+        $sql='SELECT count(ticket_id) as tickets '
+            .' FROM '.TICKET_TABLE
+            .' WHERE 1 ';
+
+        //Access control.
+        $sql.=' AND ( staff_id='.db_input($thisstaff->getId());
+
+        if(($teams=$thisstaff->getTeams()) && count(array_filter($teams)))
+            $sql.=' OR team_id IN('.implode(',', array_filter($teams)).')';
+
+        if(!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts()))
+            $sql.=' OR dept_id IN ('.implode(',', $depts).')';
+
+        $sql.=' ) ';
+
+        //Department
+        if($_REQUEST['deptId'])
+            $sql.=' AND dept_id='.db_input($_REQUEST['deptId']);
+
+        //Status
+        switch(strtolower($_REQUEST['status'])) {
+            case 'open';
+                $sql.=' AND status="open" ';
+                break;
+            case 'overdue':
+                $sql.=' AND status="open" and isoverdue=1 ';
+                break;
+            case 'closed':
+                $sql.=' AND status="closed" ';
+                break;
+        }
+        
+        if(($tickets=db_result(db_query($sql)))) {
+            $result['success'] ="Search criteria matched  $tickets tickets - view";
+        } else {
+            $result['fail']='No tickets found matching your search criteria.'.$tickets;
+        }
+            
+        return $this->json_encode($result);
+    }
+
     function acquireLock($tid) {
         global $cfg,$thisstaff;
         
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index 67d270c3f033e0db98e901d66b09fdcabf5247c6..c60bdc75059febe417307e4a77d45dca73739022 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -97,9 +97,6 @@ $deep_search=false;
 if($search):
     $qstr.='&a='.urlencode($_REQUEST['a']);
     $qstr.='&t='.urlencode($_REQUEST['t']);
-    if(isset($_REQUEST['advance_search'])){ //advance search box!
-        $qstr.='&advance_search=Search';
-    }
 
     //query
     if($searchTerm){
@@ -250,12 +247,10 @@ if(!$results_type) {
 }
 $negorder=$order=='DESC'?'ASC':'DESC'; //Negate the sorting..
 
-$basic_display=!isset($_REQUEST['advance_search'])?true:false;
-
 //YOU BREAK IT YOU FIX IT.
 ?>
 <!-- SEARCH FORM START -->
-<div id='basic' style="display:<?php echo $basic_display?'block':'none'; ?>">
+<div id='basic_search'>
     <form action="tickets.php" method="get">
     <input type="hidden" name="a" value="search">
     <table>
@@ -263,6 +258,7 @@ $basic_display=!isset($_REQUEST['advance_search'])?true:false;
             <td><input type="text" id="basic-ticket-search" name="query" size=30 value="<?php echo Format::htmlchars($_REQUEST['query']); ?>"
                 autocomplete="off" autocorrect="off" autocapitalize="off"></td>
             <td><input type="submit" name="basic_search" class="button" value="Search"></td>
+            <td>&nbsp;&nbsp;<a href="" id="go-advanced">[advanced]</a></td>
         </tr>
     </table>
     </form>
@@ -449,3 +445,107 @@ $basic_display=!isset($_REQUEST['advance_search'])?true:false;
     } ?>
     </form>
 </div>
+<div id="overlay"></div>
+<div style="display:none;" id="advanced-search">
+    <h3>Advanced Ticket Search</h3>
+    <a class="close" href="">&times;</a>
+    <form action="tickets.php" method="post" id="search" name="search">
+        <input type="hidden" name="a" value="search">
+        <fieldset class="query">
+            <label for="query">Keyword:</label>
+            <input type="input" id="query" name="query" size="20"> <em>Optional</em>
+        </fieldset>
+        <fieldset>
+            <label for="status">Status:</label>
+            <select id="status" name="status">
+                <option value="">&mdash; Any Status &mdash;</option>
+                <option value="open">Open</option>
+                <option value="overdue">Overdue</option>
+                <option value="closed">Closed</option>
+            </select>
+            <label for="deptId">Dept:</label>
+            <select id="deptId" name="deptId">
+                <option value="">&mdash; All Departments &mdash;</option>
+                <?php
+                if(($mydepts = $thisstaff->getDepts()) && ($depts=Dept::getDepartments())) {
+                    foreach($depts as $id =>$name) {
+                        if(!in_array($id, $mydepts)) continue; 
+                        echo sprintf('<option value="%d">%s</option>', $id, $name);
+                    }
+                }
+                ?>
+            </select>
+        </fieldset>
+        <fieldset class="owner">
+            <label for="assigneeId">Assigned To:</label>
+            <select id="assigneeId" name="assigneeId">
+                <option value="0">&mdash; Anyone &mdash;</option>
+                <?php
+                if(($users=Staff::getStaffMembers())) {
+                    echo '<OPTGROUP label="Staff Members ('.count($users).')">';
+                    foreach($users as $id => $name) {
+                        $k="s$id";
+                        echo sprintf('<option value="%s">%s</option>', $k, $name);
+                    }
+                    echo '</OPTGROUP>';
+                }
+                
+                if(($teams=Team::getTeams())) {
+                    echo '<OPTGROUP label="Teams ('.count($teams).')">';
+                    foreach($teams as $id => $name) {
+                        $k="t$id";
+                        echo sprintf('<option value="%s">%s</option>', $k, $name);
+                    }
+                    echo '</OPTGROUP>';
+                }
+                ?>
+            </select>
+            <label for="staffId">Closed By:</label>
+            <select id="staffId" name="staffId">
+                <option value="0">&mdash; Anyone &mdash;</option>
+                <?php
+                if(($users=Staff::getStaffMembers())) {
+                    foreach($users as $id => $name) {
+                        $k="s$id";
+                        echo sprintf('<option value="%s">%s</option>', $k, $name);
+                    }
+                }
+                ?>
+            </select>
+        </fieldset>
+        <fieldset class="date_range">
+            <label>Date Range:</label>
+            <input class="dp" type="input" size="20" name="startDate"><i></i>
+            <span>TO</span>
+            <input class="dp" type="input" size="20" name="endDate"><i></i>
+        </fieldset>
+        <fieldset class="sorting">
+            <label>Sorting:</label>
+            <select name="sort">
+                <option value="date">Create Date</option>
+            </select>
+            <select name="order">
+                <option value="desc">Descending</option>
+                <option value="asc">Ascending</option>
+            </select>
+            <select name="limit">
+                <option value="25">25 records/page</option>
+                <option value="50" selected="selected">50 records/page</option>
+                <option value="75">75 records/page</option>
+                <option value="100">100 records/page</option>
+            </select>
+        </fieldset>
+        <p>
+            <span class="buttons">
+                <input type="submit" value="Search">
+                <input type="reset" value="Reset">
+                <input type="button" value="Cancel" class="close">
+            </span>
+            <span class="spinner">
+                <img src="./images/ajax-loader.gif" width="16" height="16">
+            </span>
+        </p>
+    </form>
+    <div id="result-count">
+    </div>
+</div>
diff --git a/scp/ajax.php b/scp/ajax.php
index 471e9c710d577d662abae098ef2053dbfd702694..2b08168adda9664f710f8b4abaa47cb4c0b78801 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -43,10 +43,13 @@ $dispatcher = patterns('',
         url_get('^ticket_variables', 'ticket_variables')
     )),
     url('^/config/', patterns('ajax.config.php:ConfigAjaxAPI',
-        url_get('^ui', 'ui')
+        url_get('^ui', 'scp_ui')
     )),
     url_get('^/users$', array('ajax.users.php:UsersAjaxAPI', 'search')),
-    url_get('^/tickets$', array('ajax.tickets.php:TicketsAjaxAPI', 'search')),
+    url('^/tickets', patterns('ajax.tickets.php:TicketsAjaxAPI',
+        url_get('^/lookup', 'lookup'),
+        url_get('^$', 'search')
+    )),
     url('^/ticket/', patterns('ajax.tickets.php:TicketsAjaxAPI',
         url_get('^(?P<tid>\d+)/preview', 'previewTicket'),
         url_get('^(?P<tid>\d+)/lock', 'acquireLock'),
diff --git a/scp/css/scp.css b/scp/css/scp.css
index 5ccdbe543b0030b0fe910fc2382102bd997a4acc..de333413a94ad5f6fcb9a7aece5f4946b55ec0bd 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -1060,3 +1060,156 @@ h2 .reload {
   padding-left: 24px;
   background: url('../images/icons/page.png') 0 50% no-repeat;
 }
+
+
+/* Advanced Ticket Search */
+
+#overlay {
+    background:#000;
+    position:absolute;
+    display:none;
+    z-index:1000;
+}
+
+#advanced-search, #advanced-search * {
+    box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+}
+
+#advanced-search {
+    position:absolute;
+    padding:1em;
+    width:640px;
+    height:400px;
+    background:#fff;
+    border:1px solid #2a67ac;
+    display:none;
+    z-index:1200;
+}
+
+#advanced-search h3 {
+    color:#2a67ac;
+    font-size:20px;
+    margin:0;
+    padding:0;
+    display:inline-block;
+}
+
+#advanced-search a.close {
+    display:inline-block;
+    float:right;
+    font-size:16px;
+    color:#777;
+}
+
+#advanced-search form {
+    clear:both;
+    padding:2em 0 1em 0;
+    width:100%;
+}
+
+#advanced-search div.closed_by, #advanced-search span.spinner {
+    display:none;
+}
+
+#advanced-search fieldset {
+    margin:0;
+    padding:0.25em 0;
+    border:none;
+    overflow:hidden;
+}
+
+#advanced-search label {
+    width:100px;
+    display:inline-block;
+    text-align:right;
+    padding:10px;
+}
+
+#advanced-search fieldset input {
+    border:1px solid #ccc;
+    background:#fff;
+}
+
+#advanced-search fieldset select {
+    width:170px;
+    display:inline-block;
+}
+
+#advanced-search fieldset span {
+    width:50px;
+    display:inline-block;
+    text-align:center;
+    color:#777;
+    font-size:0.75em;
+}
+
+#advanced-search .query input {
+    width:350px;
+}
+
+#advanced-search .date_range input {
+    width:175px;
+}
+
+#advanced-search .date_range i {
+    display:inline-block;
+    margin-left:3px;
+    position:relative;
+    top:5px;
+    width:16px;
+    height:16px;
+    background:url(../images/cal.png) bottom left no-repeat;
+}
+
+#advanced-search fieldset.sorting select {
+    width:130px;
+}
+
+#advanced-search p {
+    text-align:center;
+}
+
+#advanced-search input[type="submit"],
+#advanced-search input[type="reset"],
+#advanced-search input[type="button"]
+{
+    display:inline-block;
+    margin:0;
+    height:24px;
+    line-height:24px;
+    font-weight:bold;
+    border:1px solid #666666;
+    padding:0 10px;
+    background: url('../images/grey_btn_bg.png?1312910883') top left repeat-x;
+    color: #333;
+}
+
+#advanced-search input[type="reset"], #advanced-search input[type="button"] {
+    opacity:0.7;
+}
+
+#advanced-search input[type=submit]:hover, #advanced-search input[type=submit]:active,
+#advanced-search input[type=reset]:hover, #advanced-search input[type=reset]:active {
+    background-position:bottom left;
+}
+
+#result-count div {
+    padding:5px 10px;
+    text-align:left;
+    font-weight:bold;
+    width:100%;
+    margin:0 auto;
+}
+
+#result-count .success {
+    background:#e3ffd8;
+    border:1px solid #0a0;
+}
+
+#result-count .fail {
+    background:#ffd8d8;
+    border:1px solid #a00;
+}
+
diff --git a/scp/images/ajax-loader.gif b/scp/images/ajax-loader.gif
new file mode 100644
index 0000000000000000000000000000000000000000..d42f72c723644bbf8cf8d6e1b7ff0bea7ddd305a
Binary files /dev/null and b/scp/images/ajax-loader.gif differ
diff --git a/scp/js/scp.js b/scp/js/scp.js
index 7a9e0e218d1da97b3ec4b2860f307dd1c1769d1f..37389d34b8f5510914c82c80115a0bbbc152af71 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -198,11 +198,11 @@ $(document).ready(function(){
         }
     }
 
-    /* Typeahead init */
+    /* Typeahead tickets lookup */
     $('#basic-ticket-search').typeahead({
         source: function (typeahead, query) {
             $.ajax({
-                url: "ajax.php/tickets?q="+query,
+                url: "ajax.php/tickets/lookup?q="+query,
                 dataType: 'json',
                 success: function (data) {
                     typeahead.process(data);
@@ -215,6 +215,7 @@ $(document).ready(function(){
         property: "value"
     });
 
+    /* Typeahead user lookup */
     $('#email.typeahead').typeahead({
         source: function (typeahead, query) {
             if(query.length > 2) {
@@ -235,5 +236,84 @@ $(document).ready(function(){
         property: "email"
     });
 
+    /* advanced search */
+    $("#overlay").css({
+        opacity : 0.3,
+        top     : 0,
+        left    : 0,
+        width   : $(window).width(),
+        height  : $(window).height()
+    });
+
+    $("#advanced-search").css({
+        top  : ($(window).height() / 6),
+        left : ($(window).width() / 2 - 300)
+    });
+
+    $('#go-advanced').click(function(e) {
+        e.preventDefault();
+        $('#result-count').html('');
+        $('#overlay').show();
+        $('#advanced-search').show();
+    });
+
+    $('#advanced-search').delegate('a.close, input.close', 'click', function(e) {
+        e.preventDefault();
+        $('#advanced-search').hide()
+        $('#overlay').hide();
+    }).delegate('#status', 'change', function() {
+        switch($(this).val()) {
+            case 'closed':
+                $('select#assigneeId').find('option:first').attr('selected', 'selected').parent('select');
+                $('select#assigneeId').attr('disabled','disabled');
+                $('select#staffId').removeAttr('disabled');
+                break;
+            case 'open':
+            case 'overdue':
+                $('select#staffId').find('option:first').attr('selected', 'selected').parent('select');
+                $('select#staffId').attr('disabled','disabled');
+                $('select#assigneeId').removeAttr('disabled');
+                break;
+            default:
+                $('select#staffId').removeAttr('disabled');
+                $('select#assigneeId').removeAttr('disabled');
+        }
+    });
+
+    $('#advanced-search form#search').submit(function(e) { 
+        e.preventDefault();
+        var fObj = $(this);
+        var elem = $('#advanced-search');
+        $('#result-count').html('');
+        $.ajax({
+                url: "ajax.php/tickets",
+                data: fObj.serialize(),
+                dataType: 'json',
+                beforeSend: function ( xhr ) {
+                   $('.buttons', elem).hide();
+                   $('.spinner', elem).show();
+                   return true;
+                },
+                success: function (resp) {
+                        
+                    if(resp.success) {
+                        $('#result-count').html('<div class="success">' + resp.success +'</div>');
+                    } else if (resp.fail) {
+                        $('#result-count').html('<div class="fail">' + resp.fail +'</div>');
+                    } else {
+                        $('#result-count').html('<div class="fail">Unknown error</div>');
+                    }
+                }
+            })
+            .done( function () {
+             })
+            .fail( function () {
+                $('#result-count').html('<div class="fail">Advanced search failed - try again!</div>');
+            })
+            .always( function () {
+                $('.spinner', elem).hide();
+                $('.buttons', elem).show();
+             });
+    });
 
 });